@@ -22,12 +22,15 @@ import (
22
22
"net"
23
23
"strings"
24
24
25
+ "k8s.io/klog/v2"
26
+
25
27
"github.com/aws/aws-sdk-go/aws"
26
28
"github.com/aws/aws-sdk-go/aws/credentials"
27
29
"github.com/aws/aws-sdk-go/aws/session"
28
30
"github.com/aws/aws-sdk-go/service/ec2"
29
31
30
32
v1 "k8s.io/api/core/v1"
33
+ "k8s.io/apimachinery/pkg/types"
31
34
cloudprovider "k8s.io/cloud-provider"
32
35
)
33
36
@@ -71,20 +74,10 @@ type instances struct {
71
74
72
75
// InstanceExists indicates whether a given node exists according to the cloud provider
73
76
func (i * instances ) InstanceExists (ctx context.Context , node * v1.Node ) (bool , error ) {
74
- var err error
75
- if node .Spec .ProviderID == "" {
76
- _ , err = getInstanceByPrivateDNSName (ctx , node .Name , i .ec2 )
77
- if err == cloudprovider .InstanceNotFound {
78
- return false , nil
79
- }
80
-
81
- if err != nil {
82
- return false , err
83
- }
84
- }
77
+ _ , err := i .getInstance (ctx , node )
85
78
86
- _ , err = getInstanceByProviderID (ctx , node .Spec .ProviderID , i .ec2 )
87
79
if err == cloudprovider .InstanceNotFound {
80
+ klog .V (6 ).Infof ("instance not found for node: %s" , node .Name )
88
81
return false , nil
89
82
}
90
83
@@ -97,28 +90,31 @@ func (i *instances) InstanceExists(ctx context.Context, node *v1.Node) (bool, er
97
90
98
91
// InstanceShutdown returns true if the instance is shutdown according to the cloud provider.
99
92
func (i * instances ) InstanceShutdown (ctx context.Context , node * v1.Node ) (bool , error ) {
100
- if node .Spec .ProviderID == "" {
101
- return i .instanceShutdownByPrivateDNSName (ctx , node .Name )
93
+ ec2Instance , err := i .getInstance (ctx , node )
94
+ if err != nil {
95
+ return false , err
96
+ }
97
+
98
+ if ec2Instance .State != nil {
99
+ state := aws .StringValue (ec2Instance .State .Name )
100
+ // valid state for detaching volumes
101
+ if state == ec2 .InstanceStateNameStopped {
102
+ return true , nil
103
+ }
102
104
}
103
105
104
- return i . instanceShutdownByProviderID ( ctx , node . Spec . ProviderID )
106
+ return false , nil
105
107
}
106
108
107
109
// InstanceMetadata returns the instance's metadata.
108
110
func (i * instances ) InstanceMetadata (ctx context.Context , node * v1.Node ) (* cloudprovider.InstanceMetadata , error ) {
109
111
var err error
110
112
var ec2Instance * ec2.Instance
111
- if node .Spec .ProviderID == "" {
112
- // TODO: support node name policy other than private DNS names
113
- ec2Instance , err = getInstanceByPrivateDNSName (ctx , node .Name , i .ec2 )
114
- if err != nil {
115
- return nil , err
116
- }
117
- } else {
118
- ec2Instance , err = getInstanceByProviderID (ctx , node .Spec .ProviderID , i .ec2 )
119
- if err != nil {
120
- return nil , err
121
- }
113
+
114
+ // TODO: support node name policy other than private DNS names
115
+ ec2Instance , err = i .getInstance (ctx , node )
116
+ if err != nil {
117
+ return nil , err
122
118
}
123
119
124
120
nodeAddresses , err := nodeAddressesForInstance (ec2Instance )
@@ -140,20 +136,29 @@ func (i *instances) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloud
140
136
return metadata , nil
141
137
}
142
138
143
- // getInstanceByProviderID returns the instance if the instance with the given provider id still exists.
139
+ // getInstance returns the instance if the instance with the given node info still exists.
144
140
// If false an error will be returned, the instance will be immediately deleted by the cloud controller manager.
145
- func getInstanceByProviderID (ctx context.Context , providerID string , ec2Client EC2 ) (* ec2.Instance , error ) {
146
- instanceID , err := parseInstanceIDFromProviderID (providerID )
147
- if err != nil {
148
- return nil , err
141
+ func (i * instances ) getInstance (ctx context.Context , node * v1.Node ) (* ec2.Instance , error ) {
142
+ if node .Spec .ProviderID == "" {
143
+ // get Instance by node name
144
+ klog .V (4 ).Infof ("looking for node by private DNS name %v" , node .Name )
145
+ return getInstanceByPrivateDNSName (ctx , types .NodeName (node .Name ), i .ec2 )
149
146
}
150
147
148
+ // get Instance by provider ID
149
+ klog .V (4 ).Infof ("looking for node by provider ID %v" , node .Spec .ProviderID )
150
+ return getInstanceByProviderID (ctx , node .Spec .ProviderID , i .ec2 )
151
+ }
152
+
153
+ // getInstanceByPrivateDNSName returns the instance if the instance with the given nodeName exists.
154
+ // If false an error will be returned, the instance will be immediately deleted by the cloud controller manager.
155
+ func getInstanceByPrivateDNSName (ctx context.Context , nodeName types.NodeName , ec2Client EC2 ) (* ec2.Instance , error ) {
151
156
request := & ec2.DescribeInstancesInput {
152
- InstanceIds : []* string {aws .String (instanceID )},
153
157
Filters : []* ec2.Filter {
154
- newEc2Filter ("instance-state -name" , aliveFilter ... ),
158
+ newEc2Filter ("private-dns -name" , string ( nodeName ) ),
155
159
},
156
160
}
161
+ klog .V (4 ).Infof ("looking for node by private DNS name %v" , nodeName )
157
162
158
163
instances := []* ec2.Instance {}
159
164
var nextToken * string
@@ -179,21 +184,29 @@ func getInstanceByProviderID(ctx context.Context, providerID string, ec2Client E
179
184
}
180
185
181
186
if len (instances ) > 1 {
182
- return nil , fmt .Errorf ("multiple instances found with provider ID: %s" , instanceID )
187
+ return nil , fmt .Errorf ("getInstance: multiple instances found" )
188
+ }
189
+
190
+ state := instances [0 ].State .Name
191
+ if * state == ec2 .InstanceStateNameTerminated {
192
+ return nil , fmt .Errorf ("instance %v is terminated" , instances [0 ].InstanceId )
183
193
}
184
194
185
195
return instances [0 ], nil
186
196
}
187
197
188
- // getInstanceByPrivateDNSName returns the instance if the instance with the given provider id still exists.
198
+ // getInstanceByProviderID returns the instance if the instance with the given providerID exists.
189
199
// If false an error will be returned, the instance will be immediately deleted by the cloud controller manager.
190
- func getInstanceByPrivateDNSName (ctx context.Context , nodeName string , ec2Client EC2 ) (* ec2.Instance , error ) {
200
+ func getInstanceByProviderID (ctx context.Context , providerID string , ec2Client EC2 ) (* ec2.Instance , error ) {
201
+ instanceID , err := parseInstanceIDFromProviderID (providerID )
202
+ if err != nil {
203
+ return nil , err
204
+ }
205
+
191
206
request := & ec2.DescribeInstancesInput {
192
- Filters : []* ec2.Filter {
193
- newEc2Filter ("private-dns-name" , nodeName ),
194
- newEc2Filter ("instance-state-name" , aliveFilter ... ),
195
- },
207
+ InstanceIds : []* string {aws .String (instanceID )},
196
208
}
209
+ klog .V (4 ).Infof ("looking for node by provider ID %v" , providerID )
197
210
198
211
instances := []* ec2.Instance {}
199
212
var nextToken * string
@@ -219,55 +232,18 @@ func getInstanceByPrivateDNSName(ctx context.Context, nodeName string, ec2Client
219
232
}
220
233
221
234
if len (instances ) > 1 {
222
- return nil , fmt .Errorf ("multiple instances found with private DNS name: %s" , nodeName )
223
- }
224
-
225
- return instances [0 ], nil
226
- }
227
-
228
- // instanceShutdownByProviderID returns true if the instance is shutdown according to the cloud provider.
229
- func (i * instances ) instanceShutdownByProviderID (ctx context.Context , providerID string ) (bool , error ) {
230
- ec2Instance , err := getInstanceByProviderID (ctx , providerID , i .ec2 )
231
- if err != nil {
232
- if err == cloudprovider .InstanceNotFound {
233
- // We don't have live ec2Instance
234
- return true , nil
235
- }
236
- return false , err
235
+ return nil , fmt .Errorf ("getInstance: multiple instances found" )
237
236
}
238
237
239
- if ec2Instance .State != nil {
240
- state := aws .StringValue (ec2Instance .State .Name )
241
- if state == ec2 .InstanceStateNameStopping || state == ec2 .InstanceStateNameStopped {
242
- return true , nil
243
- }
238
+ state := instances [0 ].State .Name
239
+ if * state == ec2 .InstanceStateNameTerminated {
240
+ return nil , fmt .Errorf ("instance %v is terminated" , instances [0 ].InstanceId )
244
241
}
245
242
246
- return false , nil
247
- }
248
-
249
- // instanceShutdownByPrivateDNSName returns true if the instance is shutdown according to the cloud provider.
250
- func (i * instances ) instanceShutdownByPrivateDNSName (ctx context.Context , nodeName string ) (bool , error ) {
251
- ec2Instance , err := getInstanceByPrivateDNSName (ctx , nodeName , i .ec2 )
252
- if err != nil {
253
- if err == cloudprovider .InstanceNotFound {
254
- // We don't have live ec2Instance
255
- return true , nil
256
- }
257
- return false , err
258
- }
259
-
260
- if ec2Instance .State != nil {
261
- state := aws .StringValue (ec2Instance .State .Name )
262
- if state == ec2 .InstanceStateNameStopping || state == ec2 .InstanceStateNameStopped {
263
- return true , nil
264
- }
265
- }
266
-
267
- return false , nil
243
+ return instances [0 ], nil
268
244
}
269
245
270
- // nodeAddressesForInstance returns a list of v1.NodeAddress for the give instance.
246
+ // nodeAddresses for Instance returns a list of v1.NodeAddress for the give instance.
271
247
// TODO: should we support ExternalIP by default?
272
248
func nodeAddressesForInstance (instance * ec2.Instance ) ([]v1.NodeAddress , error ) {
273
249
if instance == nil {
@@ -340,14 +316,6 @@ func parseInstanceIDFromProviderID(providerID string) (string, error) {
340
316
return instanceID , nil
341
317
}
342
318
343
- var aliveFilter = []string {
344
- ec2 .InstanceStateNamePending ,
345
- ec2 .InstanceStateNameRunning ,
346
- ec2 .InstanceStateNameShuttingDown ,
347
- ec2 .InstanceStateNameStopping ,
348
- ec2 .InstanceStateNameStopped ,
349
- }
350
-
351
319
func newEc2Filter (name string , values ... string ) * ec2.Filter {
352
320
filter := & ec2.Filter {
353
321
Name : aws .String (name ),
0 commit comments