mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-16 01:22:00 +00:00
79 lines
2.8 KiB
Go
79 lines
2.8 KiB
Go
package gateway_ec2_instance
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log/slog"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go/service/ec2"
|
|
"github.com/mulgadc/hive/hive/awserrors"
|
|
"github.com/mulgadc/hive/hive/utils"
|
|
"github.com/nats-io/nats.go"
|
|
)
|
|
|
|
// ValidateModifyInstanceAttributeInput validates the input constraints for ModifyInstanceAttribute.
|
|
// AWS rejects calls with multiple attributes set in a single request.
|
|
func ValidateModifyInstanceAttributeInput(input *ec2.ModifyInstanceAttributeInput) error {
|
|
if input == nil {
|
|
return errors.New(awserrors.ErrorInvalidParameterValue)
|
|
}
|
|
if input.InstanceId == nil || *input.InstanceId == "" {
|
|
return errors.New(awserrors.ErrorInvalidInstanceIDMalformed)
|
|
}
|
|
if !strings.HasPrefix(*input.InstanceId, "i-") {
|
|
return errors.New(awserrors.ErrorInvalidInstanceIDMalformed)
|
|
}
|
|
|
|
// Exactly one attribute must be set
|
|
count := 0
|
|
if input.InstanceType != nil {
|
|
count++
|
|
}
|
|
if input.UserData != nil {
|
|
count++
|
|
}
|
|
if count != 1 {
|
|
return errors.New(awserrors.ErrorInvalidParameterValue)
|
|
}
|
|
|
|
// Validate instance type value is non-empty if present
|
|
if input.InstanceType != nil && (input.InstanceType.Value == nil || *input.InstanceType.Value == "") {
|
|
return errors.New(awserrors.ErrorInvalidInstanceAttributeValue)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ModifyInstanceAttribute sends a modify request to the daemon via NATS.
|
|
// The daemon updates the stopped instance in KV and returns an empty response on success.
|
|
func ModifyInstanceAttribute(input *ec2.ModifyInstanceAttributeInput, natsConn *nats.Conn) (ec2.ModifyInstanceAttributeOutput, error) {
|
|
if err := ValidateModifyInstanceAttributeInput(input); err != nil {
|
|
return ec2.ModifyInstanceAttributeOutput{}, err
|
|
}
|
|
|
|
slog.Info("ModifyInstanceAttribute: Processing request", "instance_id", *input.InstanceId)
|
|
|
|
jsonData, err := json.Marshal(input)
|
|
if err != nil {
|
|
slog.Error("ModifyInstanceAttribute: Failed to marshal request", "instance_id", *input.InstanceId, "err", err)
|
|
return ec2.ModifyInstanceAttributeOutput{}, fmt.Errorf("failed to marshal request: %w", err)
|
|
}
|
|
|
|
msg, err := natsConn.Request("ec2.ModifyInstanceAttribute", jsonData, 30*time.Second)
|
|
if err != nil {
|
|
slog.Error("ModifyInstanceAttribute: Failed to send request", "instance_id", *input.InstanceId, "err", err)
|
|
return ec2.ModifyInstanceAttributeOutput{}, fmt.Errorf("failed to send modify request: %w", err)
|
|
}
|
|
|
|
if responseError, parseErr := utils.ValidateErrorPayload(msg.Data); parseErr != nil {
|
|
slog.Error("ModifyInstanceAttribute: Daemon returned error", "instance_id", *input.InstanceId, "code", *responseError.Code)
|
|
return ec2.ModifyInstanceAttributeOutput{}, errors.New(*responseError.Code)
|
|
}
|
|
|
|
slog.Info("ModifyInstanceAttribute: Completed successfully", "instance_id", *input.InstanceId)
|
|
return ec2.ModifyInstanceAttributeOutput{}, nil
|
|
}
|