in pkg/instancetypes/instancetypes.go [113:166]
func (p *Provider) Get(ctx context.Context, instanceTypes []ec2types.InstanceType) ([]*Details, error) {
p.logger.Printf("Getting instance types %v", instanceTypes)
start := time.Now()
calls := 0
defer func() {
p.logger.Printf("Took %s and %d calls to collect Instance Types", time.Since(start), calls)
}()
instanceTypeDetails := []*Details{}
describeInstanceTypeOpts := &ec2.DescribeInstanceTypesInput{}
if len(instanceTypes) != 0 {
for _, it := range instanceTypes {
if cachedIT, ok := p.cache.Get(string(it)); ok {
instanceTypeDetails = append(instanceTypeDetails, cachedIT.(*Details))
} else {
// need to reassign, so we're not sharing the loop iterators memory space
instanceType := it
describeInstanceTypeOpts.InstanceTypes = append(describeInstanceTypeOpts.InstanceTypes, instanceType)
}
}
// if we were able to retrieve all from cache, return here, else continue to do a remote lookup
if len(describeInstanceTypeOpts.InstanceTypes) == 0 {
return instanceTypeDetails, nil
}
} else if p.lastFullRefresh != nil && !p.isFullRefreshNeeded() {
for _, item := range p.cache.Items() {
instanceTypeDetails = append(instanceTypeDetails, item.Object.(*Details))
}
return instanceTypeDetails, nil
}
s := ec2.NewDescribeInstanceTypesPaginator(p.ec2Client, describeInstanceTypeOpts)
for s.HasMorePages() {
calls++
instanceTypeOutput, err := s.NextPage(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get next instance types page, %w", err)
}
for _, instanceTypeInfo := range instanceTypeOutput.InstanceTypes {
itDetails := &Details{InstanceTypeInfo: instanceTypeInfo}
instanceTypeDetails = append(instanceTypeDetails, itDetails)
p.cache.SetDefault(string(instanceTypeInfo.InstanceType), itDetails)
}
}
if len(instanceTypes) == 0 {
now := time.Now().UTC()
p.lastFullRefresh = &now
if err := p.Save(); err != nil {
return instanceTypeDetails, err
}
}
return instanceTypeDetails, nil
}