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

Commit 1b6c6bc

Browse files
committed
Wait to delete InstanceManagers and InstanceTemplates
This commit waits until all related Instances have been deleted before proceeding with the deletion of InstanceManagers and InstanceTemplates
1 parent 47c9bd5 commit 1b6c6bc

8 files changed

Lines changed: 409 additions & 28 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)