Skip to content

Commit c995a15

Browse files
committed
update the code
1 parent cab5bca commit c995a15

3 files changed

Lines changed: 131 additions & 227 deletions

File tree

pkg/networking/az_id_translator.go

Lines changed: 42 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -36,109 +36,90 @@ func NewDefaultAZIDTranslator(ec2Client services.EC2, logger logr.Logger) *defau
3636

3737
var _ AZIDTranslator = &defaultAZIDTranslator{}
3838

39-
// zoneCacheKey scopes a cached zone lookup to a single account.
40-
// Availability zone names are only meaningful within an account, so entries for different accounts
41-
// must never be shared. scope is empty for the cluster's own account and the assumed role ARN
42-
// otherwise.
43-
type zoneCacheKey struct {
44-
scope string
45-
lookup string
39+
// zoneMapping holds every availability zone of a single account, indexed by name and by ID.
40+
type zoneMapping struct {
41+
idByName map[string]string
42+
nameByID map[string]string
4643
}
4744

4845
type defaultAZIDTranslator struct {
4946
ec2Client services.EC2
5047

48+
// zoneCache maps an account scope to its zoneMapping. Availability zone names are only
49+
// meaningful within an account, so entries for different accounts must never be shared. The
50+
// scope is empty for the cluster's own account and the assumed role ARN otherwise.
5151
zoneCache *cache.Expiring
5252
zoneCacheMutex sync.RWMutex
5353

5454
logger logr.Logger
5555
}
5656

5757
func (t *defaultAZIDTranslator) TranslateAZName(ctx context.Context, assumeRoleArn string, externalId string, srcZoneName string) (*string, error) {
58-
zoneID, err := t.resolveZoneID(ctx, srcZoneName)
58+
srcZones, err := t.fetchZoneMapping(ctx, t.ec2Client, "")
5959
if err != nil {
6060
return nil, err
6161
}
62-
if zoneID == nil {
62+
zoneID, exists := srcZones.idByName[srcZoneName]
63+
if !exists {
64+
t.logger.Info("unable to resolve availability zone ID", "zoneName", srcZoneName)
6365
return nil, nil
6466
}
6567

6668
assumedRoleEC2, err := t.ec2Client.AssumeRole(ctx, assumeRoleArn, externalId)
6769
if err != nil {
6870
return nil, err
6971
}
70-
return t.resolveZoneName(ctx, assumedRoleEC2, assumeRoleArn, *zoneID)
71-
}
72-
73-
// resolveZoneID resolves a zone name to its zone ID within the cluster's own account.
74-
func (t *defaultAZIDTranslator) resolveZoneID(ctx context.Context, zoneName string) (*string, error) {
75-
cacheKey := zoneCacheKey{lookup: zoneName}
76-
if cachedZoneID, exists := t.fetchZoneFromCache(cacheKey); exists {
77-
return &cachedZoneID, nil
78-
}
79-
80-
resp, err := t.ec2Client.DescribeAvailabilityZonesWithContext(ctx, &ec2sdk.DescribeAvailabilityZonesInput{
81-
ZoneNames: []string{zoneName},
82-
})
72+
dstZones, err := t.fetchZoneMapping(ctx, assumedRoleEC2, assumeRoleArn)
8373
if err != nil {
8474
return nil, err
8575
}
86-
for _, azInfo := range resp.AvailabilityZones {
87-
if awssdk.ToString(azInfo.ZoneName) != zoneName {
88-
continue
89-
}
90-
zoneID := awssdk.ToString(azInfo.ZoneId)
91-
if zoneID == "" {
92-
continue
93-
}
94-
t.saveZoneToCache(cacheKey, zoneID)
95-
return &zoneID, nil
76+
zoneName, exists := dstZones.nameByID[zoneID]
77+
if !exists {
78+
t.logger.Info("unable to resolve availability zone name", "zoneID", zoneID, "scope", assumeRoleArn)
79+
return nil, nil
9680
}
97-
t.logger.Info("unable to resolve availability zone ID", "zoneName", zoneName)
98-
return nil, nil
81+
return &zoneName, nil
9982
}
10083

101-
// resolveZoneName resolves a zone ID to the zone name used by the account reachable via ec2Client.
102-
func (t *defaultAZIDTranslator) resolveZoneName(ctx context.Context, ec2Client services.EC2, scope string, zoneID string) (*string, error) {
103-
cacheKey := zoneCacheKey{scope: scope, lookup: zoneID}
104-
if cachedZoneName, exists := t.fetchZoneFromCache(cacheKey); exists {
105-
return &cachedZoneName, nil
84+
// fetchZoneMapping returns the availability zones visible to ec2Client, cached under scope.
85+
// The zones of an account are fetched in a single unfiltered call so that a zone missing from the
86+
// mapping is known to be unresolvable without issuing another call for it.
87+
func (t *defaultAZIDTranslator) fetchZoneMapping(ctx context.Context, ec2Client services.EC2, scope string) (*zoneMapping, error) {
88+
if cachedMapping, exists := t.fetchZoneMappingFromCache(scope); exists {
89+
return cachedMapping, nil
10690
}
10791

108-
resp, err := ec2Client.DescribeAvailabilityZonesWithContext(ctx, &ec2sdk.DescribeAvailabilityZonesInput{
109-
ZoneIds: []string{zoneID},
110-
})
92+
resp, err := ec2Client.DescribeAvailabilityZonesWithContext(ctx, &ec2sdk.DescribeAvailabilityZonesInput{})
11193
if err != nil {
11294
return nil, err
11395
}
96+
97+
mapping := &zoneMapping{
98+
idByName: make(map[string]string, len(resp.AvailabilityZones)),
99+
nameByID: make(map[string]string, len(resp.AvailabilityZones)),
100+
}
114101
for _, azInfo := range resp.AvailabilityZones {
115-
if awssdk.ToString(azInfo.ZoneId) != zoneID {
116-
continue
117-
}
118102
zoneName := awssdk.ToString(azInfo.ZoneName)
119-
if zoneName == "" {
103+
zoneID := awssdk.ToString(azInfo.ZoneId)
104+
if zoneName == "" || zoneID == "" {
120105
continue
121106
}
122-
t.saveZoneToCache(cacheKey, zoneName)
123-
return &zoneName, nil
107+
mapping.idByName[zoneName] = zoneID
108+
mapping.nameByID[zoneID] = zoneName
124109
}
125-
t.logger.Info("unable to resolve availability zone name", "zoneID", zoneID, "scope", scope)
126-
return nil, nil
110+
111+
t.zoneCacheMutex.Lock()
112+
defer t.zoneCacheMutex.Unlock()
113+
t.zoneCache.Set(scope, mapping, defaultAZIDTranslationCacheTTL)
114+
return mapping, nil
127115
}
128116

129-
func (t *defaultAZIDTranslator) fetchZoneFromCache(key zoneCacheKey) (string, bool) {
117+
func (t *defaultAZIDTranslator) fetchZoneMappingFromCache(scope string) (*zoneMapping, bool) {
130118
t.zoneCacheMutex.RLock()
131119
defer t.zoneCacheMutex.RUnlock()
132120

133-
if rawCacheItem, exists := t.zoneCache.Get(key); exists {
134-
return rawCacheItem.(string), true
121+
if rawCacheItem, exists := t.zoneCache.Get(scope); exists {
122+
return rawCacheItem.(*zoneMapping), true
135123
}
136-
return "", false
137-
}
138-
139-
func (t *defaultAZIDTranslator) saveZoneToCache(key zoneCacheKey, value string) {
140-
t.zoneCacheMutex.Lock()
141-
defer t.zoneCacheMutex.Unlock()
142-
143-
t.zoneCache.Set(key, value, defaultAZIDTranslationCacheTTL)
124+
return nil, false
144125
}

0 commit comments

Comments
 (0)