1
1
package aws
2
2
3
3
import (
4
+ "fmt"
4
5
"net"
5
6
"os"
6
7
"strings"
7
8
8
9
"github.com/aws/aws-sdk-go/aws"
9
10
"github.com/aws/aws-sdk-go/aws/endpoints"
10
11
"github.com/aws/aws-sdk-go/aws/session"
12
+ "github.com/aws/aws-sdk-go/service/ec2"
11
13
"github.com/pkg/errors"
12
14
"github.com/prometheus/client_golang/prometheus"
15
+ amerrors "k8s.io/apimachinery/pkg/util/errors"
13
16
epresolver "sigs.k8s.io/aws-load-balancer-controller/pkg/aws/endpoints"
14
17
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/metrics"
15
18
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
@@ -70,13 +73,6 @@ func NewCloud(cfg CloudConfig, metricsRegisterer prometheus.Registerer) (Cloud,
70
73
71
74
metadataSess := session .Must (session .NewSessionWithOptions (opts ))
72
75
metadata := services .NewEC2Metadata (metadataSess )
73
- if len (cfg .VpcID ) == 0 {
74
- vpcId , err := metadata .VpcID ()
75
- if err != nil {
76
- return nil , errors .Wrap (err , "failed to introspect vpcID from EC2Metadata, specify --aws-vpc-id instead if EC2Metadata is unavailable" )
77
- }
78
- cfg .VpcID = vpcId
79
- }
80
76
81
77
if len (cfg .Region ) == 0 {
82
78
region := os .Getenv ("AWS_DEFAULT_REGION" )
@@ -114,9 +110,19 @@ func NewCloud(cfg CloudConfig, metricsRegisterer prometheus.Registerer) (Cloud,
114
110
metricsCollector .InjectHandlers (& sess .Handlers )
115
111
}
116
112
113
+ ec2Service := services .NewEC2 (sess )
114
+
115
+ if len (cfg .VpcID ) == 0 {
116
+ vpcID , err := inferVPCID (metadata , ec2Service )
117
+ if err != nil {
118
+ return nil , errors .Wrap (err , "failed to introspect vpcID from EC2Metadata or Node name, specify --aws-vpc-id instead if EC2Metadata is unavailable" )
119
+ }
120
+ cfg .VpcID = vpcID
121
+ }
122
+
117
123
return & defaultCloud {
118
124
cfg : cfg ,
119
- ec2 : services . NewEC2 ( sess ) ,
125
+ ec2 : ec2Service ,
120
126
elbv2 : services .NewELBV2 (sess ),
121
127
acm : services .NewACM (sess ),
122
128
wafv2 : services .NewWAFv2 (sess ),
@@ -126,6 +132,42 @@ func NewCloud(cfg CloudConfig, metricsRegisterer prometheus.Registerer) (Cloud,
126
132
}, nil
127
133
}
128
134
135
+ func inferVPCID (metadata services.EC2Metadata , ec2Service services.EC2 ) (string , error ) {
136
+ var errList []error
137
+ vpcId , err := metadata .VpcID ()
138
+ if err == nil {
139
+ return vpcId , nil
140
+ } else {
141
+ errList = append (errList , errors .Wrap (err , "failed to fetch VPC ID from instance metadata" ))
142
+ }
143
+
144
+ nodeName := os .Getenv ("NODENAME" )
145
+ if strings .HasPrefix (nodeName , "i-" ) {
146
+ output , err := ec2Service .DescribeInstances (& ec2.DescribeInstancesInput {
147
+ InstanceIds : []* string {& nodeName },
148
+ })
149
+ if err != nil {
150
+ errList = append (errList , errors .Wrapf (err , "failed to describe instance %q" , nodeName ))
151
+ return "" , amerrors .NewAggregate (errList )
152
+ }
153
+ if len (output .Reservations ) != 1 {
154
+ errList = append (errList , fmt .Errorf ("found more than one reservation for instance %q" , nodeName ))
155
+ return "" , amerrors .NewAggregate (errList )
156
+ }
157
+ if len (output .Reservations [0 ].Instances ) != 1 {
158
+ errList = append (errList , fmt .Errorf ("found more than one instance with instance ID %q" , nodeName ))
159
+ return "" , amerrors .NewAggregate (errList )
160
+ }
161
+
162
+ vpcID := output .Reservations [0 ].Instances [0 ].VpcId
163
+ if vpcID != nil {
164
+ return * vpcID , nil
165
+ }
166
+
167
+ }
168
+ return "" , amerrors .NewAggregate (errList )
169
+ }
170
+
129
171
var _ Cloud = & defaultCloud {}
130
172
131
173
type defaultCloud struct {
0 commit comments