fix: fail DeleteLaunchTemplateVersions on the default version and report missing versions as AWS does

This commit is contained in:
Julian Sommer
2026-09-29 15:47:32 +10:00
parent 957a5eac2a
commit 72ee50f6f3
2 changed files with 31 additions and 14 deletions
@@ -514,6 +514,13 @@ func (s *LaunchTemplateServiceImpl) DeleteLaunchTemplateVersions(ctx context.Con
return nil, errors.New(awserrors.ErrorMissingParameter)
}
// Naming the default version fails the whole request, so nothing is deleted.
for _, v := range input.Versions {
if n, perr := strconv.ParseInt(aws.StringValue(v), 10, 64); perr == nil && n == header.DefaultVersionNumber {
return nil, awserrors.Errorf(awserrors.ErrorInvalidParameterValue, "The default version cannot be deleted. Either specify another version as default or delete the launch template.")
}
}
out := &ec2.DeleteLaunchTemplateVersionsOutput{}
for _, v := range input.Versions {
@@ -524,14 +531,9 @@ func (s *LaunchTemplateServiceImpl) DeleteLaunchTemplateVersions(ctx context.Con
deleteErrorItem(header, 0, awserrors.ErrorInvalidLaunchTemplateIdVersionNotFound, "invalid version number"))
continue
}
if n == header.DefaultVersionNumber {
out.UnsuccessfullyDeletedLaunchTemplateVersions = append(out.UnsuccessfullyDeletedLaunchTemplateVersions,
deleteErrorItem(header, n, awserrors.ErrorInvalidParameterValue, "cannot delete the default version of a launch template"))
continue
}
if _, err := s.getVersion(ctx, accountID, header.LaunchTemplateId, n); err != nil {
out.UnsuccessfullyDeletedLaunchTemplateVersions = append(out.UnsuccessfullyDeletedLaunchTemplateVersions,
deleteErrorItem(header, n, awserrors.ErrorInvalidLaunchTemplateIdVersionNotFound, "version does not exist"))
deleteErrorItem(header, n, launchTemplateVersionDoesNotExist, "The launch template version does not exist."))
continue
}
if err := s.kv.Delete(ctx, versionKey(accountID, header.LaunchTemplateId, n)); err != nil {
@@ -551,6 +553,10 @@ func (s *LaunchTemplateServiceImpl) DeleteLaunchTemplateVersions(ctx context.Con
return out, nil
}
// launchTemplateVersionDoesNotExist is the per-version code AWS reports in a
// DeleteLaunchTemplateVersions result; it is never a request-level error.
const launchTemplateVersionDoesNotExist = "launchTemplateVersionDoesNotExist"
func deleteErrorItem(h *LaunchTemplateHeader, n int64, code, msg string) *ec2.DeleteLaunchTemplateVersionsResponseErrorItem {
item := &ec2.DeleteLaunchTemplateVersionsResponseErrorItem{
LaunchTemplateId: aws.String(h.LaunchTemplateId),
@@ -396,15 +396,23 @@ func TestModifyLaunchTemplate_DefaultToMissingVersion(t *testing.T) {
func TestDeleteLaunchTemplateVersions_RejectDefault(t *testing.T) {
svc := setupTestService(t)
lt := createTemplate(t, svc, "web", "t3.micro") // default = v1
out, err := svc.DeleteLaunchTemplateVersions(context.Background(), &ec2.DeleteLaunchTemplateVersionsInput{
LaunchTemplateId: lt.LaunchTemplateId,
Versions: []*string{aws.String("1")},
id := aws.StringValue(lt.LaunchTemplateId)
addVersion(t, svc, id, "a", "") // v2
// The default alongside a deletable version still fails the whole request.
_, err := svc.DeleteLaunchTemplateVersions(context.Background(), &ec2.DeleteLaunchTemplateVersionsInput{
LaunchTemplateId: aws.String(id),
Versions: []*string{aws.String("2"), aws.String("1")},
}, testAccountID)
require.Error(t, err)
code, msg, ok := awserrors.ResolveErrorDetail(err)
require.True(t, ok)
assert.Equal(t, awserrors.ErrorInvalidParameterValue, code)
assert.Equal(t, "The default version cannot be deleted. Either specify another version as default or delete the launch template.", msg)
nums, err := svc.listVersionNumbers(t.Context(), testAccountID, id)
require.NoError(t, err)
assert.Empty(t, out.SuccessfullyDeletedLaunchTemplateVersions)
require.Len(t, out.UnsuccessfullyDeletedLaunchTemplateVersions, 1)
assert.Equal(t, awserrors.ErrorInvalidParameterValue,
aws.StringValue(out.UnsuccessfullyDeletedLaunchTemplateVersions[0].ResponseError.Code))
assert.ElementsMatch(t, []int64{1, 2}, nums)
}
func TestDeleteLaunchTemplateVersions_SuccessAndMissing(t *testing.T) {
@@ -421,7 +429,10 @@ func TestDeleteLaunchTemplateVersions_SuccessAndMissing(t *testing.T) {
require.Len(t, out.SuccessfullyDeletedLaunchTemplateVersions, 1)
assert.Equal(t, int64(2), aws.Int64Value(out.SuccessfullyDeletedLaunchTemplateVersions[0].VersionNumber))
require.Len(t, out.UnsuccessfullyDeletedLaunchTemplateVersions, 1)
assert.Equal(t, int64(9), aws.Int64Value(out.UnsuccessfullyDeletedLaunchTemplateVersions[0].VersionNumber))
missing := out.UnsuccessfullyDeletedLaunchTemplateVersions[0]
assert.Equal(t, int64(9), aws.Int64Value(missing.VersionNumber))
assert.Equal(t, "launchTemplateVersionDoesNotExist", aws.StringValue(missing.ResponseError.Code))
assert.Equal(t, "The launch template version does not exist.", aws.StringValue(missing.ResponseError.Message))
}
// --- DeleteLaunchTemplate ---