Sitelet https://github.com/kubernetes/kops/commit/a55887b8ec2ee82134be45a1660f48009a0d1f1d
Skip to content

Commit a55887b

Browse files
authored
Merge pull request #18327 from rifelpet/gce-instance-fix
Cherrypick GCE instance handling fixes to 1.35
2 parents 690debc + 1379d78 commit a55887b

8 files changed

Lines changed: 506 additions & 29 deletions

File tree

‎cloudmock/gce/mock_gce_cloud.go‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
compute "google.golang.org/api/compute/v1"
2424
"google.golang.org/api/storage/v1"
2525
v1 "k8s.io/api/core/v1"
26-
"k8s.io/klog/v2"
2726
"k8s.io/kops/cloudmock/gce/mockcloudresourcemanager"
2827
mockcompute "k8s.io/kops/cloudmock/gce/mockcompute"
2928
"k8s.io/kops/cloudmock/gce/mockdns"
@@ -73,13 +72,12 @@ func (c *MockGCECloud) AllResources() map[string]interface{} {
7372

7473
// GetCloudGroups is not implemented yet
7574
func (c *MockGCECloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {
76-
klog.V(8).Infof("MockGCECloud cloud provider GetCloudGroups not implemented yet")
77-
return nil, fmt.Errorf("MockGCECloud cloud provider does not support getting cloud groups at this time")
75+
return gce.GetCloudGroups(c, cluster, instancegroups, warnUnmatched, nodes)
7876
}
7977

8078
// Zones is not implemented yet
8179
func (c *MockGCECloud) Zones() ([]string, error) {
82-
return nil, fmt.Errorf("not yet implemented")
80+
return gce.GetZones(c)
8381
}
8482

8583
// WithLabels returns a copy of the MockGCECloud bound to the specified labels
@@ -170,8 +168,7 @@ func (c *MockGCECloud) Labels() map[string]string {
170168

171169
// DeleteGroup implements fi.Cloud::DeleteGroup
172170
func (c *MockGCECloud) DeleteGroup(g *cloudinstances.CloudInstanceGroup) error {
173-
return nil
174-
// return deleteCloudInstanceGroup(c, g)
171+
return gce.DeleteCloudInstanceGroup(c, g)
175172
}
176173

177174
// DeleteInstance deletes a GCE instance

‎cloudmock/gce/mockcompute/api.go‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type MockClient struct {
3737
addressClient *addressClient
3838
firewallClient *firewallClient
3939
routerClient *routerClient
40+
instanceClient *instanceClient
4041

4142
instanceTemplateClient *instanceTemplateClient
4243
instanceGroupManagerClient *instanceGroupManagerClient
@@ -49,6 +50,8 @@ var _ gce.ComputeClient = &MockClient{}
4950

5051
// NewMockClient creates a new mock client.
5152
func NewMockClient(project string) *MockClient {
53+
instanceClient := newInstanceClient()
54+
5255
return &MockClient{
5356
projectClient: newProjectClient(project),
5457
zoneClient: newZoneClient(project),
@@ -63,9 +66,10 @@ func NewMockClient(project string) *MockClient {
6366
addressClient: newAddressClient(),
6467
firewallClient: newFirewallClient(),
6568
routerClient: newRouterClient(),
69+
instanceClient: instanceClient,
6670

6771
instanceTemplateClient: newInstanceTemplateClient(),
68-
instanceGroupManagerClient: newInstanceGroupManagerClient(),
72+
instanceGroupManagerClient: newInstanceGroupManagerClient(instanceClient),
6973
targetPoolClient: newTargetPoolClient(),
7074

7175
diskClient: newDiskClient(),
@@ -158,8 +162,7 @@ func (c *MockClient) Routers() gce.RouterClient {
158162
}
159163

160164
func (c *MockClient) Instances() gce.InstanceClient {
161-
// Not implemented.
162-
return nil
165+
return c.instanceClient
163166
}
164167

165168
func (c *MockClient) InstanceTemplates() gce.InstanceTemplateClient {
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
Copyright The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package mockcompute
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"sync"
23+
24+
compute "google.golang.org/api/compute/v1"
25+
"k8s.io/kops/upup/pkg/fi/cloudup/gce"
26+
)
27+
28+
type instanceClient struct {
29+
// instances are instances keyed by project, zone, and name.
30+
instances map[string]map[string]map[string]*compute.Instance
31+
sync.Mutex
32+
}
33+
34+
var _ gce.InstanceClient = &instanceClient{}
35+
36+
func newInstanceClient() *instanceClient {
37+
return &instanceClient{
38+
instances: map[string]map[string]map[string]*compute.Instance{},
39+
}
40+
}
41+
42+
func (c *instanceClient) All() map[string]interface{} {
43+
return nil
44+
}
45+
46+
func (c *instanceClient) Insert(project, zone string, instance *compute.Instance) (*compute.Operation, error) {
47+
c.Lock()
48+
defer c.Unlock()
49+
zones, ok := c.instances[project]
50+
if !ok {
51+
zones = map[string]map[string]*compute.Instance{}
52+
c.instances[project] = zones
53+
}
54+
instances, ok := zones[zone]
55+
if !ok {
56+
instances = map[string]*compute.Instance{}
57+
zones[zone] = instances
58+
}
59+
instance.SelfLink = instance.Name
60+
instances[instance.Name] = instance
61+
62+
return doneOperation(), nil
63+
}
64+
65+
func (c *instanceClient) Delete(project, zone, name string) (*compute.Operation, error) {
66+
c.Lock()
67+
defer c.Unlock()
68+
69+
zones, ok := c.instances[project]
70+
if !ok {
71+
return nil, notFoundError()
72+
}
73+
instances, ok := zones[zone]
74+
if !ok {
75+
return nil, notFoundError()
76+
}
77+
if _, ok := instances[name]; !ok {
78+
return nil, notFoundError()
79+
}
80+
delete(instances, name)
81+
return doneOperation(), nil
82+
}
83+
84+
func (c *instanceClient) Get(project, zone, name string) (*compute.Instance, error) {
85+
c.Lock()
86+
defer c.Unlock()
87+
zones, ok := c.instances[project]
88+
if !ok {
89+
return nil, notFoundError()
90+
}
91+
res, ok := zones[zone]
92+
if !ok {
93+
return nil, notFoundError()
94+
}
95+
igm, ok := res[name]
96+
if !ok {
97+
return nil, notFoundError()
98+
}
99+
return igm, nil
100+
}
101+
102+
func (c *instanceClient) List(ctx context.Context, project, zone string) ([]*compute.Instance, error) {
103+
c.Lock()
104+
defer c.Unlock()
105+
106+
zones, ok := c.instances[project]
107+
if !ok {
108+
return nil, nil
109+
}
110+
instances, ok := zones[zone]
111+
if !ok {
112+
return nil, nil
113+
}
114+
115+
var l []*compute.Instance
116+
for _, instance := range instances {
117+
l = append(l, instance)
118+
}
119+
return l, nil
120+
}
121+
122+
func (c *instanceClient) SetMetadata(project, zone, name string, metadata *compute.Metadata) (*compute.Operation, error) {
123+
return nil, fmt.Errorf("setmetadata unimplemented")
124+
}

‎cloudmock/gce/mockcompute/instance_group_manager.go‎

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222
"sync"
23+
"time"
2324

2425
compute "google.golang.org/api/compute/v1"
2526
"k8s.io/kops/upup/pkg/fi/cloudup/gce"
@@ -28,14 +29,20 @@ import (
2829
type instanceGroupManagerClient struct {
2930
// instanceGroupManagers are instanceGroupManagers keyed by project, zone, and name.
3031
instanceGroupManagers map[string]map[string]map[string]*compute.InstanceGroupManager
32+
// managedInstances are managedInstances keyed by project, zone, and name.
33+
managedInstances map[string]map[string]map[string]*compute.ManagedInstance
34+
// instanceClient is the client for instances.
35+
instanceClient gce.InstanceClient
3136
sync.Mutex
3237
}
3338

3439
var _ gce.InstanceGroupManagerClient = &instanceGroupManagerClient{}
3540

36-
func newInstanceGroupManagerClient() *instanceGroupManagerClient {
41+
func newInstanceGroupManagerClient(instanceClient gce.InstanceClient) *instanceGroupManagerClient {
3742
return &instanceGroupManagerClient{
3843
instanceGroupManagers: map[string]map[string]map[string]*compute.InstanceGroupManager{},
44+
managedInstances: map[string]map[string]map[string]*compute.ManagedInstance{},
45+
instanceClient: instanceClient,
3946
}
4047
}
4148

@@ -56,18 +63,40 @@ func (c *instanceGroupManagerClient) All() map[string]interface{} {
5663
func (c *instanceGroupManagerClient) Insert(project, zone string, igm *compute.InstanceGroupManager) (*compute.Operation, error) {
5764
c.Lock()
5865
defer c.Unlock()
59-
zones, ok := c.instanceGroupManagers[project]
66+
igmZones, ok := c.instanceGroupManagers[project]
6067
if !ok {
61-
zones = map[string]map[string]*compute.InstanceGroupManager{}
62-
c.instanceGroupManagers[project] = zones
68+
igmZones = map[string]map[string]*compute.InstanceGroupManager{}
69+
c.instanceGroupManagers[project] = igmZones
6370
}
64-
igms, ok := zones[zone]
71+
igms, ok := igmZones[zone]
6572
if !ok {
6673
igms = map[string]*compute.InstanceGroupManager{}
67-
zones[zone] = igms
74+
igmZones[zone] = igms
6875
}
6976
igm.SelfLink = fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/zones/%s/instanceGroupManagers/%s", project, zone, igm.Name)
7077
igms[igm.Name] = igm
78+
79+
newInstance := &compute.Instance{
80+
Name: igm.Name,
81+
}
82+
83+
c.instanceClient.Insert(project, zone, newInstance)
84+
85+
instanceZones, ok := c.managedInstances[project]
86+
if !ok {
87+
instanceZones = map[string]map[string]*compute.ManagedInstance{}
88+
c.managedInstances[project] = instanceZones
89+
}
90+
_, ok = instanceZones[zone]
91+
if !ok {
92+
instanceZones[zone] = map[string]*compute.ManagedInstance{}
93+
}
94+
95+
c.managedInstances[project][zone][igm.Name] = &compute.ManagedInstance{
96+
Name: igm.Name,
97+
Instance: fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/zones/%s/instances/%s", project, zone, igm.Name),
98+
}
99+
71100
return doneOperation(), nil
72101
}
73102

@@ -126,8 +155,23 @@ func (c *instanceGroupManagerClient) List(ctx context.Context, project, zone str
126155
}
127156

128157
func (c *instanceGroupManagerClient) ListManagedInstances(ctx context.Context, project, zone, name string) ([]*compute.ManagedInstance, error) {
129-
var instances []*compute.ManagedInstance
130-
return instances, nil
158+
c.Lock()
159+
defer c.Unlock()
160+
161+
zones, ok := c.managedInstances[project]
162+
if !ok {
163+
return nil, nil
164+
}
165+
instances, ok := zones[zone]
166+
if !ok {
167+
return nil, nil
168+
}
169+
170+
var l []*compute.ManagedInstance
171+
for _, instance := range instances {
172+
l = append(l, instance)
173+
}
174+
return l, nil
131175
}
132176

133177
func (c *instanceGroupManagerClient) RecreateInstances(project, zone, name, id string) (*compute.Operation, error) {
@@ -143,5 +187,28 @@ func (c *instanceGroupManagerClient) SetInstanceTemplate(project, zone, name, in
143187
}
144188

145189
func (c *instanceGroupManagerClient) Resize(project, zone, name string, newSize int64) (*compute.Operation, error) {
190+
go func() {
191+
if newSize == 0 {
192+
// Simulates a Long Operation when resizing
193+
time.Sleep(20 * time.Millisecond)
194+
195+
c.Lock()
196+
defer c.Unlock()
197+
198+
// Delete all Instances from GCE
199+
for _, zones := range c.managedInstances[project] {
200+
for _, instance := range zones {
201+
c.instanceClient.Delete(project, zone, instance.Name)
202+
}
203+
}
204+
205+
zones, ok := c.managedInstances[project]
206+
if !ok {
207+
return
208+
}
209+
210+
zones[zone] = nil
211+
}
212+
}()
146213
return doneOperation(), nil
147214
}

0 commit comments

Comments
 (0)