Skip to content

Commit 6cb715e

Browse files
sadasur4f4
andcommitted
Fix and improve locking session and AWS Metadata access
This fix eliminates the need for mutexSubnets to update subnet information within AWS metadata. It also updates populateSubnets to take care of getting VPC and subnets once for the installation eliminating duplicate code that could be prone to errors. Co-authored-by: Rafael F. <[email protected]>
1 parent b5f0545 commit 6cb715e

File tree

2 files changed

+25
-37
lines changed

2 files changed

+25
-37
lines changed

pkg/asset/installconfig/aws/metadata.go

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ type Metadata struct {
2626
Subnets []string `json:"subnets,omitempty"`
2727
Services []typesaws.ServiceEndpoint `json:"services,omitempty"`
2828

29-
mutex sync.Mutex
30-
mutexSubnets sync.Mutex
29+
mutex sync.Mutex
3130
}
3231

3332
// NewMetadata initializes a new Metadata object.
@@ -66,10 +65,9 @@ func (m *Metadata) AvailabilityZones(ctx context.Context) ([]string, error) {
6665
if err != nil {
6766
return nil, err
6867
}
69-
7068
m.availabilityZones, err = availabilityZones(ctx, session, m.Region)
7169
if err != nil {
72-
return nil, errors.Wrap(err, "creating AWS session")
70+
return nil, errors.Wrap(err, "error retrieving Availability Zones")
7371
}
7472
}
7573

@@ -82,9 +80,8 @@ func (m *Metadata) AvailabilityZones(ctx context.Context) ([]string, error) {
8280
func (m *Metadata) EdgeSubnets(ctx context.Context) (map[string]Subnet, error) {
8381
err := m.populateSubnets(ctx)
8482
if err != nil {
85-
return nil, err
83+
return nil, errors.Wrap(err, "error retrieving Edge Subnets")
8684
}
87-
8885
return m.edgeSubnets, nil
8986
}
9087

@@ -94,9 +91,8 @@ func (m *Metadata) EdgeSubnets(ctx context.Context) (map[string]Subnet, error) {
9491
func (m *Metadata) PrivateSubnets(ctx context.Context) (map[string]Subnet, error) {
9592
err := m.populateSubnets(ctx)
9693
if err != nil {
97-
return nil, err
94+
return nil, errors.Wrap(err, "error retrieving Private Subnets")
9895
}
99-
10096
return m.privateSubnets, nil
10197
}
10298

@@ -106,25 +102,34 @@ func (m *Metadata) PrivateSubnets(ctx context.Context) (map[string]Subnet, error
106102
func (m *Metadata) PublicSubnets(ctx context.Context) (map[string]Subnet, error) {
107103
err := m.populateSubnets(ctx)
108104
if err != nil {
109-
return nil, err
105+
return nil, errors.Wrap(err, "error retrieving Public Subnets")
110106
}
111-
112107
return m.publicSubnets, nil
113108
}
114109

115-
func (m *Metadata) populateSubnets(ctx context.Context) error {
116-
if len(m.publicSubnets) > 0 || len(m.privateSubnets) > 0 {
117-
return nil
110+
// VPC retrieves the VPC ID containing PublicSubnets and PrivateSubnets.
111+
func (m *Metadata) VPC(ctx context.Context) (string, error) {
112+
err := m.populateSubnets(ctx)
113+
if err != nil {
114+
return "", errors.Wrap(err, "error retrieving VPC")
118115
}
116+
return m.vpc, nil
117+
}
118+
119+
func (m *Metadata) populateSubnets(ctx context.Context) error {
120+
m.mutex.Lock()
121+
defer m.mutex.Unlock()
119122

120123
if len(m.Subnets) == 0 {
121124
return errors.New("no subnets configured")
122125
}
123126

124-
m.mutexSubnets.Lock()
125-
defer m.mutexSubnets.Unlock()
127+
if m.vpc != "" || len(m.privateSubnets) > 0 || len(m.publicSubnets) > 0 || len(m.edgeSubnets) > 0 {
128+
// Call to populate subnets has already happened
129+
return nil
130+
}
126131

127-
session, err := m.Session(ctx)
132+
session, err := m.unlockedSession(ctx)
128133
if err != nil {
129134
return err
130135
}
@@ -137,25 +142,6 @@ func (m *Metadata) populateSubnets(ctx context.Context) error {
137142
return err
138143
}
139144

140-
// VPC retrieves the VPC ID containing PublicSubnets and PrivateSubnets.
141-
func (m *Metadata) VPC(ctx context.Context) (string, error) {
142-
m.mutex.Lock()
143-
defer m.mutex.Unlock()
144-
145-
if m.vpc == "" {
146-
if len(m.Subnets) == 0 {
147-
return "", errors.New("cannot calculate VPC without configured subnets")
148-
}
149-
150-
err := m.populateSubnets(ctx)
151-
if err != nil {
152-
return "", err
153-
}
154-
}
155-
156-
return m.vpc, nil
157-
}
158-
159145
// InstanceTypes retrieves instance type metadata indexed by InstanceType for the configured region.
160146
func (m *Metadata) InstanceTypes(ctx context.Context) (map[string]InstanceType, error) {
161147
m.mutex.Lock()
@@ -169,7 +155,7 @@ func (m *Metadata) InstanceTypes(ctx context.Context) (map[string]InstanceType,
169155

170156
m.instanceTypes, err = instanceTypes(ctx, session, m.Region)
171157
if err != nil {
172-
return nil, errors.Wrap(err, "listing instance types")
158+
return nil, errors.Wrap(err, "error listing instance types")
173159
}
174160
}
175161

pkg/asset/installconfig/aws/validation_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ func TestValidate(t *testing.T) {
540540
privateSubnets: map[string]Subnet{},
541541
publicSubnets: map[string]Subnet{},
542542
edgeSubnets: validEdgeSubnets(),
543-
expectErr: `^platform\.aws\.subnets: Invalid value: \[\]string{\"valid-public-subnet-edge-a\", \"valid-public-subnet-edge-b\", \"valid-public-subnet-edge-c\"}: edge pool. no subnets configured$`,
543+
expectErr: `^\[platform\.aws\.subnets: Invalid value: \[\]string{\"valid-public-subnet-edge-a\", \"valid-public-subnet-edge-b\", \"valid-public-subnet-edge-c\"}: No private subnets found, controlPlane\.platform\.aws\.zones: Invalid value: \[\]string{\"a\", \"b\", \"c\"}: No subnets provided for zones \[a b c\], compute\[0\]\.platform\.aws\.zones: Invalid value: \[\]string{\"a\", \"b\", \"c\"}: No subnets provided for zones \[a b c\]]$`,
544544
}, {
545545
name: "invalid no subnet for control plane zones",
546546
installConfig: func() *types.InstallConfig {
@@ -749,6 +749,7 @@ func TestValidate(t *testing.T) {
749749
publicSubnets: test.publicSubnets,
750750
edgeSubnets: test.edgeSubnets,
751751
instanceTypes: test.instanceTypes,
752+
Subnets: test.installConfig.Platform.AWS.Subnets,
752753
}
753754
if test.proxy != "" {
754755
os.Setenv("HTTP_PROXY", test.proxy)
@@ -881,6 +882,7 @@ func TestValidateForProvisioning(t *testing.T) {
881882
instanceTypes: validInstanceTypes(),
882883
Region: editedInstallConfig.AWS.Region,
883884
vpc: "valid-private-subnet-a",
885+
Subnets: editedInstallConfig.Platform.AWS.Subnets,
884886
}
885887

886888
err := ValidateForProvisioning(route53Client, editedInstallConfig, meta)

0 commit comments

Comments
 (0)