mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 09:01:31 +00:00
105 lines
3.6 KiB
Go
105 lines
3.6 KiB
Go
//go:build e2e
|
|
|
|
// Cluster-discovery helpers that memoize EC2 catalog lookups on the Fixture.
|
|
// First call pays the API cost; later callers in the same process hit the cache.
|
|
package harness
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/service/ec2"
|
|
)
|
|
|
|
// DiscoverDefaultAZ returns the first AZ reported as "available" by
|
|
// DescribeAvailabilityZones. Memoized per fixture.
|
|
func DiscoverDefaultAZ(t *testing.T, fx *Fixture) string {
|
|
t.Helper()
|
|
az, err := fx.ensureOnce(t, "discover:default-az", func() (string, func() error, error) {
|
|
out, derr := fx.EC2.DescribeAvailabilityZones(&ec2.DescribeAvailabilityZonesInput{})
|
|
if derr != nil {
|
|
return "", nil, fmt.Errorf("DescribeAvailabilityZones: %w", derr)
|
|
}
|
|
if len(out.AvailabilityZones) == 0 {
|
|
return "", nil, fmt.Errorf("no availability zones returned")
|
|
}
|
|
name := aws.StringValue(out.AvailabilityZones[0].ZoneName)
|
|
state := aws.StringValue(out.AvailabilityZones[0].State)
|
|
if state != "available" {
|
|
return "", nil, fmt.Errorf("AZ %s state %q (want available)", name, state)
|
|
}
|
|
return name, nil, nil
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("DiscoverDefaultAZ: %v", err)
|
|
}
|
|
return az
|
|
}
|
|
|
|
// DiscoverNanoInstanceType returns the first instance type whose name contains
|
|
// "nano" along with the architecture reported by its ProcessorInfo. Memoized
|
|
// per fixture. Mirrors the picker logic from the bash run-e2e.sh driver.
|
|
func DiscoverNanoInstanceType(t *testing.T, fx *Fixture) (instanceType, arch string) {
|
|
t.Helper()
|
|
combined, err := fx.ensureOnce(t, "discover:nano-instance-type", func() (string, func() error, error) {
|
|
out, derr := fx.EC2.DescribeInstanceTypes(&ec2.DescribeInstanceTypesInput{})
|
|
if derr != nil {
|
|
return "", nil, fmt.Errorf("DescribeInstanceTypes: %w", derr)
|
|
}
|
|
for _, it := range out.InstanceTypes {
|
|
name := aws.StringValue(it.InstanceType)
|
|
if !strings.Contains(name, "nano") {
|
|
continue
|
|
}
|
|
if it.ProcessorInfo == nil || len(it.ProcessorInfo.SupportedArchitectures) == 0 {
|
|
continue
|
|
}
|
|
a := aws.StringValue(it.ProcessorInfo.SupportedArchitectures[0])
|
|
// Pack into a single memo value (string) — split below.
|
|
return name + "|" + a, nil, nil
|
|
}
|
|
return "", nil, fmt.Errorf("no nano instance type available (saw %d types)", len(out.InstanceTypes))
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("DiscoverNanoInstanceType: %v", err)
|
|
}
|
|
instanceType, arch, ok := strings.Cut(combined, "|")
|
|
if !ok {
|
|
t.Fatalf("DiscoverNanoInstanceType: malformed memo value %q", combined)
|
|
}
|
|
return instanceType, arch
|
|
}
|
|
|
|
// DiscoverUbuntuAMI returns the AMI ID for the architecture-appropriate Ubuntu
|
|
// gold image. Tries ubuntu-26.04 first, falls back to ubuntu-24.04.
|
|
// Routes through EnsureAMI so the state-available poll and memoization apply.
|
|
func DiscoverUbuntuAMI(t *testing.T, fx *Fixture, arch string) string {
|
|
t.Helper()
|
|
if arch == "" {
|
|
t.Fatalf("DiscoverUbuntuAMI: arch required")
|
|
}
|
|
id, err := fx.ensureOnce(t, "discover:ubuntu-ami:"+arch, func() (string, func() error, error) {
|
|
candidates := []string{
|
|
"ami-ubuntu-26.04-" + arch,
|
|
"ami-ubuntu-24.04-" + arch,
|
|
}
|
|
for _, name := range candidates {
|
|
out, derr := fx.EC2.DescribeImages(&ec2.DescribeImagesInput{
|
|
Filters: []*ec2.Filter{
|
|
{Name: aws.String("name"), Values: []*string{aws.String(name)}},
|
|
},
|
|
})
|
|
if derr == nil && len(out.Images) > 0 {
|
|
return aws.StringValue(out.Images[0].ImageId), nil, nil
|
|
}
|
|
}
|
|
return "", nil, fmt.Errorf("no Ubuntu AMI found (tried: %v)", candidates)
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("DiscoverUbuntuAMI: %v", err)
|
|
}
|
|
return EnsureAMI(t, fx, AMISource{Existing: id})
|
|
}
|