Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions bastion/ami.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,32 @@ func GetAndValidateAmi(sess *session.Session, input string, instance_type string
return ami, nil
}

input, err := GetArchitecture(sess, instance_type)
parameter, err := amiParameterForAlias(input, func() (string, error) {
return GetArchitecture(sess, instance_type)
})
if err != nil {
return "", err
}

if parameter, ok := amis[input]; ok {
ami, err := GetAmiFromParameter(sess, parameter)
return GetAmiFromParameter(sess, parameter)
}

// amiParameterForAlias returns the SSM parameter path for a named AMI alias.
// Amazon Linux aliases (and unrecognised names) are resolved to the image
// matching the instance type's architecture via detectArch. Other named
// aliases, such as "windows", map directly to their own parameter.
func amiParameterForAlias(input string, detectArch func() (string, error)) (string, error) {
alias := input
if _, known := amis[input]; !known || strings.HasPrefix(input, "amazon-linux") {
arch, err := detectArch()
if err != nil {
return "", err
}
return ami, nil
alias = arch
}

if parameter, ok := amis[alias]; ok {
return parameter, nil
}
return "", errors.New("unable to find ami")
}
Expand Down
51 changes: 51 additions & 0 deletions bastion/ami_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package bastion

import (
"errors"
"testing"
)

func TestAmiParameterForAlias(t *testing.T) {
cases := []struct {
name string
input string
arch string
want string
wantDetect bool
}{
{"windows alias is not replaced by architecture", "windows", "amazon-linux", amis["windows"], false},
{"amazon-linux on x86_64", "amazon-linux", "amazon-linux", amis["amazon-linux"], true},
{"amazon-linux on arm64", "amazon-linux", "amazon-linux-arm64", amis["amazon-linux-arm64"], true},
{"amazon-linux-arm64 follows instance architecture", "amazon-linux-arm64", "amazon-linux", amis["amazon-linux"], true},
{"unknown alias falls back to architecture", "something-else", "amazon-linux-arm64", amis["amazon-linux-arm64"], true},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
detected := false
got, err := amiParameterForAlias(tc.input, func() (string, error) {
detected = true
return tc.arch, nil
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got != tc.want {
t.Errorf("got %q, want %q", got, tc.want)
}
if detected != tc.wantDetect {
t.Errorf("architecture detection called = %v, want %v", detected, tc.wantDetect)
}
})
}
}

func TestAmiParameterForAliasDetectError(t *testing.T) {
wantErr := errors.New("describe failed")
_, err := amiParameterForAlias("amazon-linux", func() (string, error) {
return "", wantErr
})
if !errors.Is(err, wantErr) {
t.Fatalf("got error %v, want %v", err, wantErr)
}
}
Loading