Skip to content

Commit 596c6fb

Browse files
committed
e2e test for node deleted in cloud provider
1 parent 697c231 commit 596c6fb

File tree

16 files changed

+228
-47
lines changed

16 files changed

+228
-47
lines changed

hack/.golint_failures

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ test/e2e/apps
695695
test/e2e/auth
696696
test/e2e/autoscaling
697697
test/e2e/chaosmonkey
698+
test/e2e/cloud
698699
test/e2e/common
699700
test/e2e/framework
700701
test/e2e/framework/ingress

pkg/cloudprovider/providers/aws/aws.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,7 @@ func extractNodeAddresses(instance *ec2.Instance) ([]v1.NodeAddress, error) {
13321332
// This method will not be called from the node that is requesting this ID. i.e. metadata service
13331333
// and other local methods cannot be used here
13341334
func (c *Cloud) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error) {
1335-
instanceID, err := kubernetesInstanceID(providerID).mapToAWSInstanceID()
1335+
instanceID, err := KubernetesInstanceID(providerID).MapToAWSInstanceID()
13361336
if err != nil {
13371337
return nil, err
13381338
}
@@ -1348,7 +1348,7 @@ func (c *Cloud) NodeAddressesByProviderID(ctx context.Context, providerID string
13481348
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists.
13491349
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
13501350
func (c *Cloud) InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error) {
1351-
instanceID, err := kubernetesInstanceID(providerID).mapToAWSInstanceID()
1351+
instanceID, err := KubernetesInstanceID(providerID).MapToAWSInstanceID()
13521352
if err != nil {
13531353
return false, err
13541354
}
@@ -1379,7 +1379,7 @@ func (c *Cloud) InstanceExistsByProviderID(ctx context.Context, providerID strin
13791379

13801380
// InstanceShutdownByProviderID returns true if the instance is in safe state to detach volumes
13811381
func (c *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) {
1382-
instanceID, err := kubernetesInstanceID(providerID).mapToAWSInstanceID()
1382+
instanceID, err := KubernetesInstanceID(providerID).MapToAWSInstanceID()
13831383
if err != nil {
13841384
return false, err
13851385
}
@@ -1435,7 +1435,7 @@ func (c *Cloud) InstanceID(ctx context.Context, nodeName types.NodeName) (string
14351435
// This method will not be called from the node that is requesting this ID. i.e. metadata service
14361436
// and other local methods cannot be used here
14371437
func (c *Cloud) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) {
1438-
instanceID, err := kubernetesInstanceID(providerID).mapToAWSInstanceID()
1438+
instanceID, err := KubernetesInstanceID(providerID).MapToAWSInstanceID()
14391439
if err != nil {
14401440
return "", err
14411441
}
@@ -1521,7 +1521,7 @@ func (c *Cloud) GetZone(ctx context.Context) (cloudprovider.Zone, error) {
15211521
// This is particularly useful in external cloud providers where the kubelet
15221522
// does not initialize node data.
15231523
func (c *Cloud) GetZoneByProviderID(ctx context.Context, providerID string) (cloudprovider.Zone, error) {
1524-
instanceID, err := kubernetesInstanceID(providerID).mapToAWSInstanceID()
1524+
instanceID, err := KubernetesInstanceID(providerID).MapToAWSInstanceID()
15251525
if err != nil {
15261526
return cloudprovider.Zone{}, err
15271527
}
@@ -1602,7 +1602,7 @@ func newAWSInstance(ec2Service EC2, instance *ec2.Instance) *awsInstance {
16021602

16031603
// Gets the full information about this instance from the EC2 API
16041604
func (i *awsInstance) describeInstance() (*ec2.Instance, error) {
1605-
return describeInstance(i.ec2, awsInstanceID(i.awsID))
1605+
return describeInstance(i.ec2, InstanceID(i.awsID))
16061606
}
16071607

16081608
// Gets the mountDevice already assigned to the volume, or assigns an unused mountDevice.
@@ -3787,7 +3787,7 @@ func (c *Cloud) getTaggedSecurityGroups() (map[string]*ec2.SecurityGroup, error)
37873787

37883788
// Open security group ingress rules on the instances so that the load balancer can talk to them
37893789
// Will also remove any security groups ingress rules for the load balancer that are _not_ needed for allInstances
3790-
func (c *Cloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalancerDescription, instances map[awsInstanceID]*ec2.Instance) error {
3790+
func (c *Cloud) updateInstanceSecurityGroupsForLoadBalancer(lb *elb.LoadBalancerDescription, instances map[InstanceID]*ec2.Instance) error {
37913791
if c.cfg.Global.DisableSecurityGroupIngress {
37923792
return nil
37933793
}

pkg/cloudprovider/providers/aws/aws_loadbalancer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ func (c *Cloud) updateInstanceSecurityGroupsForNLBTraffic(actualGroups []*ec2.Se
863863
}
864864

865865
// Add SG rules for a given NLB
866-
func (c *Cloud) updateInstanceSecurityGroupsForNLB(mappings []nlbPortMapping, instances map[awsInstanceID]*ec2.Instance, lbName string, clientCidrs []string) error {
866+
func (c *Cloud) updateInstanceSecurityGroupsForNLB(mappings []nlbPortMapping, instances map[InstanceID]*ec2.Instance, lbName string, clientCidrs []string) error {
867867
if c.cfg.Global.DisableSecurityGroupIngress {
868868
return nil
869869
}
@@ -1380,7 +1380,7 @@ func (c *Cloud) ensureLoadBalancerHealthCheck(loadBalancer *elb.LoadBalancerDesc
13801380
}
13811381

13821382
// Makes sure that exactly the specified hosts are registered as instances with the load balancer
1383-
func (c *Cloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstances []*elb.Instance, instanceIDs map[awsInstanceID]*ec2.Instance) error {
1383+
func (c *Cloud) ensureLoadBalancerInstances(loadBalancerName string, lbInstances []*elb.Instance, instanceIDs map[InstanceID]*ec2.Instance) error {
13841384
expected := sets.NewString()
13851385
for id := range instanceIDs {
13861386
expected.Insert(string(id))
@@ -1557,7 +1557,7 @@ func proxyProtocolEnabled(backend *elb.BackendServerDescription) bool {
15571557
// findInstancesForELB gets the EC2 instances corresponding to the Nodes, for setting up an ELB
15581558
// We ignore Nodes (with a log message) where the instanceid cannot be determined from the provider,
15591559
// and we ignore instances which are not found
1560-
func (c *Cloud) findInstancesForELB(nodes []*v1.Node) (map[awsInstanceID]*ec2.Instance, error) {
1560+
func (c *Cloud) findInstancesForELB(nodes []*v1.Node) (map[InstanceID]*ec2.Instance, error) {
15611561
// Map to instance ids ignoring Nodes where we cannot find the id (but logging)
15621562
instanceIDs := mapToAWSInstanceIDsTolerant(nodes)
15631563

pkg/cloudprovider/providers/aws/instances.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,26 @@ import (
3434
// awsInstanceRegMatch represents Regex Match for AWS instance.
3535
var awsInstanceRegMatch = regexp.MustCompile("^i-[^/]*$")
3636

37-
// awsInstanceID represents the ID of the instance in the AWS API, e.g. i-12345678
37+
// InstanceID represents the ID of the instance in the AWS API, e.g. i-12345678
3838
// The "traditional" format is "i-12345678"
3939
// A new longer format is also being introduced: "i-12345678abcdef01"
4040
// We should not assume anything about the length or format, though it seems
4141
// reasonable to assume that instances will continue to start with "i-".
42-
type awsInstanceID string
42+
type InstanceID string
4343

44-
func (i awsInstanceID) awsString() *string {
44+
func (i InstanceID) awsString() *string {
4545
return aws.String(string(i))
4646
}
4747

48-
// kubernetesInstanceID represents the id for an instance in the kubernetes API;
48+
// KubernetesInstanceID represents the id for an instance in the kubernetes API;
4949
// the following form
5050
// * aws:///<zone>/<awsInstanceId>
5151
// * aws:////<awsInstanceId>
5252
// * <awsInstanceId>
53-
type kubernetesInstanceID string
53+
type KubernetesInstanceID string
5454

55-
// mapToAWSInstanceID extracts the awsInstanceID from the kubernetesInstanceID
56-
func (name kubernetesInstanceID) mapToAWSInstanceID() (awsInstanceID, error) {
55+
// MapToAWSInstanceID extracts the InstanceID from the KubernetesInstanceID
56+
func (name KubernetesInstanceID) MapToAWSInstanceID() (InstanceID, error) {
5757
s := string(name)
5858

5959
if !strings.HasPrefix(s, "aws://") {
@@ -85,17 +85,17 @@ func (name kubernetesInstanceID) mapToAWSInstanceID() (awsInstanceID, error) {
8585
return "", fmt.Errorf("Invalid format for AWS instance (%s)", name)
8686
}
8787

88-
return awsInstanceID(awsID), nil
88+
return InstanceID(awsID), nil
8989
}
9090

91-
// mapToAWSInstanceID extracts the awsInstanceIDs from the Nodes, returning an error if a Node cannot be mapped
92-
func mapToAWSInstanceIDs(nodes []*v1.Node) ([]awsInstanceID, error) {
93-
var instanceIDs []awsInstanceID
91+
// mapToAWSInstanceID extracts the InstanceIDs from the Nodes, returning an error if a Node cannot be mapped
92+
func mapToAWSInstanceIDs(nodes []*v1.Node) ([]InstanceID, error) {
93+
var instanceIDs []InstanceID
9494
for _, node := range nodes {
9595
if node.Spec.ProviderID == "" {
9696
return nil, fmt.Errorf("node %q did not have ProviderID set", node.Name)
9797
}
98-
instanceID, err := kubernetesInstanceID(node.Spec.ProviderID).mapToAWSInstanceID()
98+
instanceID, err := KubernetesInstanceID(node.Spec.ProviderID).MapToAWSInstanceID()
9999
if err != nil {
100100
return nil, fmt.Errorf("unable to parse ProviderID %q for node %q", node.Spec.ProviderID, node.Name)
101101
}
@@ -105,15 +105,15 @@ func mapToAWSInstanceIDs(nodes []*v1.Node) ([]awsInstanceID, error) {
105105
return instanceIDs, nil
106106
}
107107

108-
// mapToAWSInstanceIDsTolerant extracts the awsInstanceIDs from the Nodes, skipping Nodes that cannot be mapped
109-
func mapToAWSInstanceIDsTolerant(nodes []*v1.Node) []awsInstanceID {
110-
var instanceIDs []awsInstanceID
108+
// mapToAWSInstanceIDsTolerant extracts the InstanceIDs from the Nodes, skipping Nodes that cannot be mapped
109+
func mapToAWSInstanceIDsTolerant(nodes []*v1.Node) []InstanceID {
110+
var instanceIDs []InstanceID
111111
for _, node := range nodes {
112112
if node.Spec.ProviderID == "" {
113113
klog.Warningf("node %q did not have ProviderID set", node.Name)
114114
continue
115115
}
116-
instanceID, err := kubernetesInstanceID(node.Spec.ProviderID).mapToAWSInstanceID()
116+
instanceID, err := KubernetesInstanceID(node.Spec.ProviderID).MapToAWSInstanceID()
117117
if err != nil {
118118
klog.Warningf("unable to parse ProviderID %q for node %q", node.Spec.ProviderID, node.Name)
119119
continue
@@ -125,7 +125,7 @@ func mapToAWSInstanceIDsTolerant(nodes []*v1.Node) []awsInstanceID {
125125
}
126126

127127
// Gets the full information about this instance from the EC2 API
128-
func describeInstance(ec2Client EC2, instanceID awsInstanceID) (*ec2.Instance, error) {
128+
func describeInstance(ec2Client EC2, instanceID InstanceID) (*ec2.Instance, error) {
129129
request := &ec2.DescribeInstancesInput{
130130
InstanceIds: []*string{instanceID.awsString()},
131131
}
@@ -164,9 +164,9 @@ func (c *instanceCache) describeAllInstancesUncached() (*allInstancesSnapshot, e
164164
return nil, err
165165
}
166166

167-
m := make(map[awsInstanceID]*ec2.Instance)
167+
m := make(map[InstanceID]*ec2.Instance)
168168
for _, i := range instances {
169-
id := awsInstanceID(aws.StringValue(i.InstanceId))
169+
id := InstanceID(aws.StringValue(i.InstanceId))
170170
m[id] = i
171171
}
172172

@@ -191,9 +191,9 @@ type cacheCriteria struct {
191191
// If set to 0 (i.e. unset), cached values will not time out because of age.
192192
MaxAge time.Duration
193193

194-
// HasInstances is a list of awsInstanceIDs that must be in a cached snapshot for it to be considered valid.
194+
// HasInstances is a list of InstanceIDs that must be in a cached snapshot for it to be considered valid.
195195
// If an instance is not found in the cached snapshot, the snapshot be ignored and we will re-fetch.
196-
HasInstances []awsInstanceID
196+
HasInstances []InstanceID
197197
}
198198

199199
// describeAllInstancesCached returns all instances, using cached results if applicable
@@ -257,12 +257,12 @@ func (s *allInstancesSnapshot) MeetsCriteria(criteria cacheCriteria) bool {
257257
// along with the timestamp for cache-invalidation purposes
258258
type allInstancesSnapshot struct {
259259
timestamp time.Time
260-
instances map[awsInstanceID]*ec2.Instance
260+
instances map[InstanceID]*ec2.Instance
261261
}
262262

263263
// FindInstances returns the instances corresponding to the specified ids. If an id is not found, it is ignored.
264-
func (s *allInstancesSnapshot) FindInstances(ids []awsInstanceID) map[awsInstanceID]*ec2.Instance {
265-
m := make(map[awsInstanceID]*ec2.Instance)
264+
func (s *allInstancesSnapshot) FindInstances(ids []InstanceID) map[InstanceID]*ec2.Instance {
265+
m := make(map[InstanceID]*ec2.Instance)
266266
for _, id := range ids {
267267
instance := s.instances[id]
268268
if instance != nil {

pkg/cloudprovider/providers/aws/instances_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import (
2929

3030
func TestMapToAWSInstanceIDs(t *testing.T) {
3131
tests := []struct {
32-
Kubernetes kubernetesInstanceID
33-
Aws awsInstanceID
32+
Kubernetes KubernetesInstanceID
33+
Aws InstanceID
3434
ExpectError bool
3535
}{
3636
{
@@ -80,7 +80,7 @@ func TestMapToAWSInstanceIDs(t *testing.T) {
8080
}
8181

8282
for _, test := range tests {
83-
awsID, err := test.Kubernetes.mapToAWSInstanceID()
83+
awsID, err := test.Kubernetes.MapToAWSInstanceID()
8484
if err != nil {
8585
if !test.ExpectError {
8686
t.Errorf("unexpected error parsing %s: %v", test.Kubernetes, err)
@@ -139,18 +139,18 @@ func TestSnapshotMeetsCriteria(t *testing.T) {
139139
t.Errorf("Snapshot did not honor MaxAge")
140140
}
141141

142-
if snapshot.MeetsCriteria(cacheCriteria{HasInstances: []awsInstanceID{awsInstanceID("i-12345678")}}) {
142+
if snapshot.MeetsCriteria(cacheCriteria{HasInstances: []InstanceID{InstanceID("i-12345678")}}) {
143143
t.Errorf("Snapshot did not honor HasInstances with missing instances")
144144
}
145145

146-
snapshot.instances = make(map[awsInstanceID]*ec2.Instance)
147-
snapshot.instances[awsInstanceID("i-12345678")] = &ec2.Instance{}
146+
snapshot.instances = make(map[InstanceID]*ec2.Instance)
147+
snapshot.instances[InstanceID("i-12345678")] = &ec2.Instance{}
148148

149-
if !snapshot.MeetsCriteria(cacheCriteria{HasInstances: []awsInstanceID{awsInstanceID("i-12345678")}}) {
149+
if !snapshot.MeetsCriteria(cacheCriteria{HasInstances: []InstanceID{InstanceID("i-12345678")}}) {
150150
t.Errorf("Snapshot did not honor HasInstances with matching instances")
151151
}
152152

153-
if snapshot.MeetsCriteria(cacheCriteria{HasInstances: []awsInstanceID{awsInstanceID("i-12345678"), awsInstanceID("i-00000000")}}) {
153+
if snapshot.MeetsCriteria(cacheCriteria{HasInstances: []InstanceID{InstanceID("i-12345678"), InstanceID("i-00000000")}}) {
154154
t.Errorf("Snapshot did not honor HasInstances with partially matching instances")
155155
}
156156
}
@@ -170,22 +170,22 @@ func TestOlderThan(t *testing.T) {
170170
func TestSnapshotFindInstances(t *testing.T) {
171171
snapshot := &allInstancesSnapshot{}
172172

173-
snapshot.instances = make(map[awsInstanceID]*ec2.Instance)
173+
snapshot.instances = make(map[InstanceID]*ec2.Instance)
174174
{
175-
id := awsInstanceID("i-12345678")
175+
id := InstanceID("i-12345678")
176176
snapshot.instances[id] = &ec2.Instance{InstanceId: id.awsString()}
177177
}
178178
{
179-
id := awsInstanceID("i-23456789")
179+
id := InstanceID("i-23456789")
180180
snapshot.instances[id] = &ec2.Instance{InstanceId: id.awsString()}
181181
}
182182

183-
instances := snapshot.FindInstances([]awsInstanceID{awsInstanceID("i-12345678"), awsInstanceID("i-23456789"), awsInstanceID("i-00000000")})
183+
instances := snapshot.FindInstances([]InstanceID{InstanceID("i-12345678"), InstanceID("i-23456789"), InstanceID("i-00000000")})
184184
if len(instances) != 2 {
185185
t.Errorf("findInstances returned %d results, expected 2", len(instances))
186186
}
187187

188-
for _, id := range []awsInstanceID{awsInstanceID("i-12345678"), awsInstanceID("i-23456789")} {
188+
for _, id := range []InstanceID{InstanceID("i-12345678"), InstanceID("i-23456789")} {
189189
i := instances[id]
190190
if i == nil {
191191
t.Errorf("findInstances did not return %s", id)

test/e2e/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ go_test(
1616
"//test/e2e/apps:go_default_library",
1717
"//test/e2e/auth:go_default_library",
1818
"//test/e2e/autoscaling:go_default_library",
19+
"//test/e2e/cloud:go_default_library",
1920
"//test/e2e/common:go_default_library",
2021
"//test/e2e/framework:go_default_library",
2122
"//test/e2e/framework/testfiles:go_default_library",
@@ -104,6 +105,7 @@ filegroup(
104105
"//test/e2e/auth:all-srcs",
105106
"//test/e2e/autoscaling:all-srcs",
106107
"//test/e2e/chaosmonkey:all-srcs",
108+
"//test/e2e/cloud:all-srcs",
107109
"//test/e2e/common:all-srcs",
108110
"//test/e2e/framework:all-srcs",
109111
"//test/e2e/generated:all-srcs",

test/e2e/cloud/BUILD

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = [
6+
"framework.go",
7+
"nodes.go",
8+
],
9+
importpath = "k8s.io/kubernetes/test/e2e/cloud",
10+
visibility = ["//visibility:public"],
11+
deps = [
12+
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
13+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
14+
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
15+
"//test/e2e/framework:go_default_library",
16+
"//vendor/github.com/onsi/ginkgo:go_default_library",
17+
"//vendor/github.com/onsi/gomega:go_default_library",
18+
],
19+
)
20+
21+
filegroup(
22+
name = "package-srcs",
23+
srcs = glob(["**"]),
24+
tags = ["automanaged"],
25+
visibility = ["//visibility:private"],
26+
)
27+
28+
filegroup(
29+
name = "all-srcs",
30+
srcs = [":package-srcs"],
31+
tags = ["automanaged"],
32+
visibility = ["//visibility:public"],
33+
)

test/e2e/cloud/OWNERS

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# See the OWNERS docs at https://go.k8s.io/owners
2+
approvers:
3+
- andrewsykim
4+
- cheftako
5+
- mcrute
6+
- d-nishi
7+
reviewers:
8+
- andrewsykim
9+
- cheftako
10+
- mcrute
11+
- d-nishi
12+
13+
labels:
14+
- sig/cloud-provider

test/e2e/cloud/framework.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
Copyright 2019 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 cloud
18+
19+
import "k8s.io/kubernetes/test/e2e/framework"
20+
21+
func SIGDescribe(text string, body func()) bool {
22+
return framework.KubeDescribe("[sig-cloud-provider] "+text, body)
23+
}

0 commit comments

Comments
 (0)