mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
Improved unit-testing and framework for service events
This commit is contained in:
@@ -1,129 +0,0 @@
|
||||
package awsparser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/mulgadc/hive/hive/utils"
|
||||
)
|
||||
|
||||
/*
|
||||
XML error
|
||||
|
||||
2025-10-02 20:19:36,786 - MainThread - urllib3.connectionpool - DEBUG - https://ec2.ap-southeast-2.amazonaws.com:443 "POST / HTTP/1.1" 400 None
|
||||
2025-10-02 20:19:36,787 - MainThread - botocore.parsers - DEBUG - Response headers: {'x-amzn-RequestId': 'dc74f0b6-b4dd-4aec-afb1-3d32539e0955', 'Cache-Control': 'no-cache, no-store', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'vary': 'accept-encoding', 'Content-Type': 'text/xml;charset=UTF-8', 'Transfer-Encoding': 'chunked', 'Date': 'Thu, 02 Oct 2025 12:19:36 GMT', 'Connection': 'close', 'Server': 'AmazonEC2'}
|
||||
2025-10-02 20:19:36,788 - MainThread - botocore.parsers - DEBUG - Response body:
|
||||
b'<?xml version="1.0" encoding="UTF-8"?>\n<Response><Errors><Error><Code>InvalidParameterValue</Code><Message>Invalid value \'t3.mcro\' for InstanceType.</Message></Error></Errors><RequestID>dc74f0b6-b4dd-4aec-afb1-3d32539e0955</RequestID></Response>'
|
||||
|
||||
*/
|
||||
|
||||
type runInstancesResponse struct {
|
||||
XMLName xml.Name `xml:"RunInstancesResponse"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
RunInstancesResult runInstancesResult `xml:"RunInstancesResult"`
|
||||
ResponseMetadata responseMetadata `xml:"ResponseMetadata"`
|
||||
}
|
||||
|
||||
type runInstancesResult struct {
|
||||
Reservation *ec2.Reservation `xml:"reservationSet>item"`
|
||||
}
|
||||
|
||||
type responseMetadata struct {
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
func EC2_Process_RunInstances(jsonData []byte) (output []byte, err error) {
|
||||
|
||||
var input ec2.RunInstancesInput
|
||||
err = json.Unmarshal(jsonData, &input)
|
||||
if err != nil {
|
||||
return output, fmt.Errorf("failed to unmarshal JSON to RunInstancesInput: %w", err)
|
||||
}
|
||||
|
||||
// Here you would add the logic to actually create the instance in your system.
|
||||
// For this example, we'll just create a dummy response.
|
||||
|
||||
instance := &ec2.Instance{
|
||||
InstanceId: aws.String("i-0123456789abcdef0"),
|
||||
State: &ec2.InstanceState{
|
||||
Code: aws.Int64(16),
|
||||
Name: aws.String("running"),
|
||||
},
|
||||
ImageId: input.ImageId,
|
||||
InstanceType: input.InstanceType,
|
||||
KeyName: input.KeyName,
|
||||
SubnetId: input.SubnetId,
|
||||
}
|
||||
|
||||
reservation := &ec2.Reservation{
|
||||
Instances: []*ec2.Instance{instance},
|
||||
OwnerId: aws.String("123456789012"),
|
||||
}
|
||||
|
||||
// Return as JSON, to simulate the NATS response
|
||||
jsonResponse, err := json.Marshal(reservation)
|
||||
if err != nil {
|
||||
return output, fmt.Errorf("failed to marshal reservation to JSON: %w", err)
|
||||
}
|
||||
|
||||
return jsonResponse, nil
|
||||
|
||||
}
|
||||
|
||||
func EC2_RunInstances(input *ec2.RunInstancesInput) (output bytes.Buffer, err error) {
|
||||
|
||||
// Simple validation
|
||||
if input.MinCount == nil || input.MaxCount == nil || *input.MinCount < 1 || *input.MaxCount < 1 || *input.MinCount > *input.MaxCount {
|
||||
return output, fmt.Errorf("Invalid MinCount or MaxCount")
|
||||
}
|
||||
if input.ImageId == nil || *input.ImageId == "" {
|
||||
return output, fmt.Errorf("ImageId is required")
|
||||
}
|
||||
if input.InstanceType == nil || *input.InstanceType == "" {
|
||||
return output, fmt.Errorf("InstanceType is required")
|
||||
}
|
||||
|
||||
// Marshal to JSON, to send over the wire for processing (NATS)
|
||||
jsonData, err := json.Marshal(input)
|
||||
if err != nil {
|
||||
return output, fmt.Errorf("failed to marshal input to JSON: %w", err)
|
||||
}
|
||||
|
||||
// Run the simulated JSON request via NATS, which will return a JSON response
|
||||
jsonResp, err := EC2_Process_RunInstances(jsonData)
|
||||
|
||||
if err != nil {
|
||||
return output, fmt.Errorf("failed to process RunInstances request: %w", err)
|
||||
}
|
||||
|
||||
// Unmarshal the JSON response back into a Reservation struct
|
||||
var reservation ec2.Reservation
|
||||
err = json.Unmarshal(jsonResp, &reservation)
|
||||
if err != nil {
|
||||
return output, fmt.Errorf("failed to unmarshal JSON response to Reservation: %w", err)
|
||||
}
|
||||
|
||||
// Convert to XML
|
||||
payload := runInstancesResponse{
|
||||
Xmlns: "http://ec2.amazonaws.com/doc/2016-11-15/",
|
||||
RunInstancesResult: runInstancesResult{
|
||||
Reservation: &reservation,
|
||||
},
|
||||
ResponseMetadata: responseMetadata{
|
||||
RequestID: "00000000-0000-0000-0000-000000000000",
|
||||
},
|
||||
}
|
||||
|
||||
output, err = utils.MarshalToXML(payload)
|
||||
if err != nil {
|
||||
return output, errors.New("failed to marshal response to XML")
|
||||
}
|
||||
|
||||
return output, nil
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package awsparser
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseRunInstance(t *testing.T) {
|
||||
|
||||
runInstance := &ec2.RunInstancesInput{
|
||||
ImageId: aws.String("ami-0abcdef1234567890"),
|
||||
InstanceType: aws.String("t2.micro"),
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: aws.String("my-key-pair"),
|
||||
SecurityGroupIds: []*string{
|
||||
aws.String("sg-0123456789abcdef0"),
|
||||
},
|
||||
SubnetId: aws.String("subnet-6e7f829e"),
|
||||
}
|
||||
|
||||
// Call the function to process the RunInstances request
|
||||
response, err := EC2_RunInstances(runInstance)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to run instances: %v", err)
|
||||
}
|
||||
|
||||
spew.Dump(response)
|
||||
}
|
||||
|
||||
func TestInvalidRunInstance(t *testing.T) {
|
||||
|
||||
runInstance := &ec2.RunInstancesInput{
|
||||
ImageId: aws.String("ami-0abcdef1234567890"),
|
||||
InstanceType: aws.String("t2.micro"),
|
||||
MinCount: aws.Int64(0),
|
||||
MaxCount: aws.Int64(0),
|
||||
KeyName: aws.String("my-key-pair"),
|
||||
SecurityGroupIds: []*string{
|
||||
aws.String("sg-0123456789abcdef0"),
|
||||
},
|
||||
SubnetId: aws.String("subnet-6e7f829e"),
|
||||
}
|
||||
// Call the function to process the RunInstances request
|
||||
response, err := EC2_RunInstances(runInstance)
|
||||
|
||||
assert.Error(t, err, "Expected error for invalid RunInstances input")
|
||||
|
||||
spew.Dump(response)
|
||||
}
|
||||
|
||||
/*
|
||||
func TestGenerateEC2ErrorResponse(t *testing.T) {
|
||||
|
||||
errorCode := "InvalidInstanceID.NotFound"
|
||||
errorMessage := "The instance ID 'i-1234567890abcdef0' does not exist"
|
||||
requestId := "123e4567-e89b-12d3-a456-426614174000"
|
||||
|
||||
xmlResponse := GenerateEC2ErrorResponse(errorCode, errorMessage, requestId)
|
||||
|
||||
assert.Contains(t, string(xmlResponse), "InvalidInstanceID.NotFound")
|
||||
}
|
||||
*/
|
||||
+38
-31
@@ -3,9 +3,13 @@ package gateway
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/mulgadc/hive/hive/awsec2query"
|
||||
gateway_ec2_core "github.com/mulgadc/hive/hive/gateway/ec2/core"
|
||||
gateway_ec2_instance "github.com/mulgadc/hive/hive/gateway/ec2/instance"
|
||||
"github.com/mulgadc/hive/hive/utils"
|
||||
)
|
||||
|
||||
func (gw *GatewayConfig) EC2_Request(ctx *fiber.Ctx) error {
|
||||
@@ -21,7 +25,39 @@ func (gw *GatewayConfig) EC2_Request(ctx *fiber.Ctx) error {
|
||||
case "DescribeInstances":
|
||||
xmlOutput, err = gateway_ec2_instance.DescribeInstances(ctx, queryArgs)
|
||||
case "RunInstances":
|
||||
xmlOutput, err = gateway_ec2_instance.RunInstances(ctx, queryArgs)
|
||||
|
||||
var input = &ec2.RunInstancesInput{}
|
||||
err = awsec2query.QueryParamsToStruct(queryArgs, input)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
output, err := gateway_ec2_instance.RunInstances(input)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert to XML
|
||||
payload := utils.GenerateXMLPayload("RunInstanceResponse", output)
|
||||
|
||||
spew.Dump(payload)
|
||||
|
||||
/*
|
||||
payload := gateway_ec2_instance.RunInstancesResponse{
|
||||
Reservation: &output,
|
||||
}
|
||||
*/
|
||||
|
||||
xmlBuffer, err := utils.MarshalToXML(payload)
|
||||
|
||||
xmlOutput = xmlBuffer.Bytes()
|
||||
|
||||
if err != nil {
|
||||
return errors.New("failed to marshal response to XML")
|
||||
}
|
||||
|
||||
case "CreateKeyPair":
|
||||
xmlOutput, err = gateway_ec2_core.CreateKeyPair(ctx, queryArgs)
|
||||
default:
|
||||
@@ -34,6 +70,7 @@ func (gw *GatewayConfig) EC2_Request(ctx *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
ctx.Status(fiber.StatusOK).Type("text/xml").Send(xmlOutput)
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
@@ -154,34 +191,4 @@ func (gw *GatewayConfig) EC2_DescribeInstances(ctx *fiber.Ctx, args map[string]s
|
||||
return ctx.SendString(response)
|
||||
}
|
||||
|
||||
func (gw *GatewayConfig) EC2_RunInstances(ctx *fiber.Ctx, args map[string]string) error {
|
||||
|
||||
slog.Info("EC2 RunInstances called")
|
||||
|
||||
// Convert HTTP post args, to the input struct
|
||||
var ec2RunInstance = &ec2.RunInstancesInput{}
|
||||
awsec2query.QueryParamsToStruct(args, ec2RunInstance)
|
||||
|
||||
// Send the query
|
||||
xmlResponse, err := awsparser.EC2_RunInstances(ec2RunInstance)
|
||||
|
||||
if err != nil {
|
||||
slog.Error("EC2 RunInstances error", "error", err)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "EC2 RunInstances error")
|
||||
}
|
||||
|
||||
// Return the XML response
|
||||
ctx.Set("Content-Type", "text/xml")
|
||||
return ctx.XML(xmlResponse)
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (gw *GatewayConfig) EC2_CreateKeyPair(ctx *fiber.Ctx, args map[string]string) error {
|
||||
slog.Info("EC2 CreateKeyPair called")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -4,22 +4,16 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/mulgadc/hive/hive/awsec2query"
|
||||
"github.com/mulgadc/hive/hive/utils"
|
||||
)
|
||||
|
||||
type runInstancesResponse struct {
|
||||
type RunInstancesResponse struct {
|
||||
Reservation *ec2.Reservation `locationName:"RunInstancesResponse"`
|
||||
}
|
||||
|
||||
type runInstancesResult struct {
|
||||
Reservation *ec2.Reservation `xml:"reservationSet>item"`
|
||||
}
|
||||
|
||||
/*
|
||||
Sample JSON:
|
||||
|
||||
@@ -134,58 +128,60 @@ Sample JSON:
|
||||
},
|
||||
*/
|
||||
|
||||
// AUTO-GENERATED: RunInstances
|
||||
// Generated from Function name: RunInstances
|
||||
func RunInstances(ctx *fiber.Ctx, args map[string]string) ([]byte, error) {
|
||||
func RunInstances(input *ec2.RunInstancesInput) (reservation ec2.Reservation, err error) {
|
||||
|
||||
// Check required args from JSON above
|
||||
// required:[
|
||||
// "MaxCount",
|
||||
// "MinCount"
|
||||
// ]
|
||||
if _, ok := args["MaxCount"]; !ok {
|
||||
return nil, errors.New("InvalidParameter")
|
||||
}
|
||||
if _, ok := args["MinCount"]; !ok {
|
||||
return nil, errors.New("InvalidParameter")
|
||||
|
||||
if *input.MinCount == 0 {
|
||||
return reservation, errors.New("InvalidParameterValue")
|
||||
}
|
||||
|
||||
// Generated from input shape: RunInstancesRequest
|
||||
var input = &ec2.RunInstancesInput{}
|
||||
awsec2query.QueryParamsToStruct(args, input)
|
||||
if *input.MaxCount == 0 {
|
||||
return reservation, errors.New("InvalidParameterValue")
|
||||
}
|
||||
|
||||
// Additional validation from EC2 spec
|
||||
if *input.MinCount > *input.MaxCount {
|
||||
return reservation, errors.New("InvalidParameterValue")
|
||||
}
|
||||
|
||||
if *input.ImageId == "" {
|
||||
return reservation, errors.New("MissingParameter")
|
||||
}
|
||||
|
||||
if *input.InstanceType == "" {
|
||||
return reservation, errors.New("MissingParameter")
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(*aws.String(*input.ImageId), "ami-") {
|
||||
return reservation, errors.New("InvalidAMIID.Malformed")
|
||||
|
||||
}
|
||||
|
||||
// Marshal to JSON, to send over the wire for processing (NATS)
|
||||
jsonData, err := json.Marshal(input)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal input to JSON: %w", err)
|
||||
return reservation, fmt.Errorf("failed to marshal input to JSON: %w", err)
|
||||
}
|
||||
|
||||
// Run the simulated JSON request via NATS, which will return a JSON response
|
||||
jsonResp, err := EC2_Process_RunInstances(jsonData)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to process RunInstances request: %w", err)
|
||||
return reservation, fmt.Errorf("failed to process RunInstances request: %w", err)
|
||||
}
|
||||
|
||||
// Unmarshal the JSON response back into a Reservation struct
|
||||
var reservation ec2.Reservation
|
||||
err = json.Unmarshal(jsonResp, &reservation)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal JSON response to Reservation: %w", err)
|
||||
return reservation, fmt.Errorf("failed to unmarshal JSON response to Reservation: %w", err)
|
||||
}
|
||||
|
||||
// Convert to XML
|
||||
payload := runInstancesResponse{
|
||||
Reservation: &reservation,
|
||||
}
|
||||
|
||||
output, err := utils.MarshalToXML(payload)
|
||||
|
||||
if err != nil {
|
||||
return output.Bytes(), errors.New("failed to marshal response to XML")
|
||||
}
|
||||
|
||||
return output.Bytes(), nil
|
||||
return reservation, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
package gateway_ec2_instance
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseRunInstances(t *testing.T) {
|
||||
|
||||
var defaults = ec2.RunInstancesInput{
|
||||
ImageId: aws.String("ami-0abcdef1234567890"),
|
||||
InstanceType: aws.String("t2.micro"),
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: aws.String("my-key-pair"),
|
||||
SecurityGroupIds: []*string{
|
||||
aws.String("sg-0123456789abcdef0"),
|
||||
},
|
||||
SubnetId: aws.String("subnet-6e7f829e"),
|
||||
}
|
||||
|
||||
// Group multiple tests
|
||||
tests := []struct {
|
||||
name string
|
||||
input *ec2.RunInstancesInput
|
||||
want error
|
||||
}{
|
||||
|
||||
{
|
||||
name: "InvalidMinCount",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: defaults.ImageId,
|
||||
InstanceType: defaults.InstanceType,
|
||||
MinCount: aws.Int64(0),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: errors.New("InvalidParameterValue"),
|
||||
},
|
||||
|
||||
{
|
||||
name: "InvalidMaxCount",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: defaults.ImageId,
|
||||
InstanceType: defaults.InstanceType,
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(0),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: errors.New("InvalidParameterValue"),
|
||||
},
|
||||
|
||||
{
|
||||
name: "InvalidMinCount",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: defaults.ImageId,
|
||||
InstanceType: defaults.InstanceType,
|
||||
MinCount: aws.Int64(0),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: errors.New("InvalidParameterValue"),
|
||||
},
|
||||
|
||||
{
|
||||
name: "InvalidNoImageId",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: aws.String(""),
|
||||
InstanceType: defaults.InstanceType,
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: errors.New("MissingParameter"),
|
||||
},
|
||||
|
||||
{
|
||||
name: "InvalidNoInstanceType",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: defaults.ImageId,
|
||||
InstanceType: aws.String(""),
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: errors.New("MissingParameter"),
|
||||
},
|
||||
|
||||
{
|
||||
name: "InvalidNoInstanceType",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: aws.String("invalid-name-here"),
|
||||
InstanceType: defaults.InstanceType,
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: errors.New("InvalidAMIID.Malformed"),
|
||||
},
|
||||
|
||||
// Successful test
|
||||
{
|
||||
name: "ValidTest",
|
||||
input: &ec2.RunInstancesInput{
|
||||
ImageId: defaults.ImageId,
|
||||
InstanceType: defaults.InstanceType,
|
||||
MinCount: aws.Int64(1),
|
||||
MaxCount: aws.Int64(1),
|
||||
KeyName: defaults.KeyName,
|
||||
SecurityGroupIds: defaults.SecurityGroupIds,
|
||||
SubnetId: defaults.SubnetId,
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
response, err := RunInstances(test.input)
|
||||
|
||||
// Use assert to check if the error is as expected
|
||||
assert.Equal(t, test.want, err)
|
||||
|
||||
if err != nil {
|
||||
assert.Len(t, response.Instances, 0)
|
||||
//assert.Nil(t, response)
|
||||
} else {
|
||||
|
||||
// Check expected output
|
||||
assert.Len(t, response.Instances, 1)
|
||||
|
||||
// ImageID returned
|
||||
if len(response.Instances) > 0 {
|
||||
|
||||
// ImageId matches our AMI
|
||||
assert.Equal(t, defaults.ImageId, response.Instances[0].ImageId)
|
||||
|
||||
// InstanceID starts with i-
|
||||
assert.True(t, true, strings.HasPrefix(*response.Instances[0].ImageId, "i-"))
|
||||
|
||||
// InstanceType matches
|
||||
assert.Equal(t, defaults.InstanceType, response.Instances[0].InstanceType)
|
||||
|
||||
// KeyName matches
|
||||
assert.Equal(t, defaults.KeyName, response.Instances[0].KeyName)
|
||||
|
||||
// State should be 16, booting.
|
||||
assert.Equal(t, aws.Int64(16), response.Instances[0].State.Code)
|
||||
|
||||
assert.Equal(t, aws.String("running"), response.Instances[0].State.Name)
|
||||
|
||||
// Subnet should match
|
||||
assert.Equal(t, defaults.SubnetId, response.Instances[0].SubnetId)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// Additional test
|
||||
|
||||
}
|
||||
@@ -39,4 +39,7 @@ var ErrorLookup = map[string]ErrorMessage{
|
||||
Message: "You are not authorized to perform this operation.",
|
||||
},
|
||||
"UnsupportedOperation": {HTTPCode: 400, Message: "The action requested is not supported."},
|
||||
|
||||
// AMI
|
||||
"InvalidAMIID.Malformed": {HTTPCode: 400, Message: "The specified AMI ID is malformed. Ensure that you provide the full AMI ID, in the form ami-xxxxxxxxxxxxxxxxx."},
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/mulgadc/hive/hive/awsec2query"
|
||||
"github.com/mulgadc/predastore/s3"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -255,3 +256,16 @@ func GenerateEC2ErrorResponse(code, message, requestID string) (output []byte) {
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func ParseArgsToStruct(input *interface{}, args map[string]string) (err error) {
|
||||
|
||||
// Generated from input shape: RunInstancesRequest
|
||||
err = awsec2query.QueryParamsToStruct(args, input)
|
||||
|
||||
if err != nil {
|
||||
return errors.New("InvalidParameter")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -217,3 +218,18 @@ func MarshalToXML(payload interface{}) (bytes.Buffer, error) {
|
||||
return buf, nil
|
||||
|
||||
}
|
||||
|
||||
// wrapWithLocation decorates payload with the requested locationName tag.
|
||||
func GenerateXMLPayload(locationName string, payload interface{}) interface{} {
|
||||
t := reflect.StructOf([]reflect.StructField{
|
||||
{
|
||||
Name: "Value",
|
||||
Type: reflect.TypeOf(payload),
|
||||
Tag: reflect.StructTag(`locationName:"` + locationName + `"`),
|
||||
},
|
||||
})
|
||||
|
||||
v := reflect.New(t).Elem()
|
||||
v.Field(0).Set(reflect.ValueOf(payload))
|
||||
return v.Interface()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user