From 820f620e34006699de1105859301146aaf491ca5 Mon Sep 17 00:00:00 2001 From: Julian Sommer <115516918+juliansommer@users.noreply.github.com> Date: Wed, 25 Mar 2026 13:54:24 +1000 Subject: [PATCH] feat: aws tf template --- scripts/iac/aws/main.tf | 16 ++++++++-------- spinifex/config/config.go | 11 +++++++++++ spinifex/config/config_test.go | 2 +- spinifex/handlers/ec2/image/service_impl.go | 6 +++++- .../handlers/ec2/image/service_impl_test.go | 17 +++++++++++++++++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/scripts/iac/aws/main.tf b/scripts/iac/aws/main.tf index eca6e7705..57ff7d8ed 100644 --- a/scripts/iac/aws/main.tf +++ b/scripts/iac/aws/main.tf @@ -26,10 +26,10 @@ variable "region" { # Set these environment variables or use terraform.tfvars: # export AWS_ACCESS_KEY_ID=your_access_key # export AWS_SECRET_ACCESS_KEY=your_secret_key -# export TF_VAR_mulgaos_endpoint=http://localhost:8080 +# export TF_VAR_mulgaos_endpoint=https://localhost:9999 variable "mulgaos_endpoint" { type = string - default = "http://localhost:8080" + default = "https://localhost:9999" description = "MulgaOS API endpoint (awsd gateway)" } @@ -57,15 +57,15 @@ data "aws_availability_zones" "available" { state = "available" } -# Debian 12 AMI (official Debian account) -# For MulgaOS, you may need to import a local AMI first +# Debian 12 AMI +# For MulgaOS, need to import a local AMI first data "aws_ami" "debian12" { most_recent = true - owners = ["136693071363"] # Debian official + owners = ["000000000000"] # Spinifex system images (on AWS use "136693071363" for Debian official) filter { name = "name" - values = ["debian-12-amd64-*"] + values = ["*debian-12*"] } filter { @@ -96,9 +96,9 @@ resource "local_file" "hive_test_pem" { file_permission = "0600" } -# 1: VPC 10.1.1.0/16 +# 1: VPC 10.1.0.0/16 resource "aws_vpc" "main" { - cidr_block = "10.1.1.0/16" + cidr_block = "10.1.0.0/16" enable_dns_hostnames = true enable_dns_support = true diff --git a/spinifex/config/config.go b/spinifex/config/config.go index 22fbf4d34..ce60b6287 100644 --- a/spinifex/config/config.go +++ b/spinifex/config/config.go @@ -5,6 +5,7 @@ import ( "log/slog" "os" "slices" + "strings" "github.com/spf13/viper" ) @@ -194,5 +195,15 @@ func LoadConfig(configPath string) (*ClusterConfig, error) { return nil, fmt.Errorf("error unmarshaling config: %w", err) } + // Normalize the local node's bind address: 0.0.0.0 means "listen on all + // interfaces" but is not a valid connect address. Only rewrite for the + // local node — remote nodes use real IPs that must not be changed. + if local, ok := config.Nodes[config.Node]; ok { + if strings.HasPrefix(local.Predastore.Host, "0.0.0.0") { + local.Predastore.Host = strings.Replace(local.Predastore.Host, "0.0.0.0", "127.0.0.1", 1) + config.Nodes[config.Node] = local + } + } + return &config, nil } diff --git a/spinifex/config/config_test.go b/spinifex/config/config_test.go index 69f0b37ab..0f512a7fe 100644 --- a/spinifex/config/config_test.go +++ b/spinifex/config/config_test.go @@ -205,7 +205,7 @@ expected_nodes = 3 assert.Equal(t, "0.0.0.0:4222", n.NATS.Host) assert.Equal(t, "secret-token", n.NATS.ACL.Token) assert.Equal(t, "test-subject", n.NATS.Sub.Subject) - assert.Equal(t, "0.0.0.0:8443", n.Predastore.Host) + assert.Equal(t, "127.0.0.1:8443", n.Predastore.Host) // 0.0.0.0 normalized to loopback assert.Equal(t, "mybucket", n.Predastore.Bucket) assert.Equal(t, "AK", n.Predastore.AccessKey) assert.Equal(t, "/data", n.Predastore.BaseDir) diff --git a/spinifex/handlers/ec2/image/service_impl.go b/spinifex/handlers/ec2/image/service_impl.go index 608263798..3cee49fd3 100644 --- a/spinifex/handlers/ec2/image/service_impl.go +++ b/spinifex/handlers/ec2/image/service_impl.go @@ -186,9 +186,13 @@ func (s *ImageServiceImpl) DescribeImages(input *ec2.DescribeImagesInput, accoun found = true } default: - // Match by explicit account ID + // Match by explicit account ID. System AMIs are stored + // with a non-account owner (e.g. "spinifex") but report + // GlobalAccountID in the response, so match against both. if amiOwner == *owner { found = true + } else if isSystemAMI && *owner == utils.GlobalAccountID { + found = true } } if found { diff --git a/spinifex/handlers/ec2/image/service_impl_test.go b/spinifex/handlers/ec2/image/service_impl_test.go index 302b21f4e..1fe2e137c 100644 --- a/spinifex/handlers/ec2/image/service_impl_test.go +++ b/spinifex/handlers/ec2/image/service_impl_test.go @@ -418,6 +418,23 @@ func TestDescribeImages_SystemAMIVisibleToAll(t *testing.T) { require.Len(t, result2.Images, 1) } +func TestDescribeImages_FilterSystemAMIByGlobalAccountID(t *testing.T) { + svc, store := setupTestImageService(t) + + // Create a system AMI (non-account-ID owner like "spinifex") + createTestAMIConfigWithOwner(t, store, "ami-sysfilter", "system-debian", "spinifex") + + // Filtering by GlobalAccountID ("000000000000") should match system AMIs + // because that's the OwnerId returned in the response + result, err := svc.DescribeImages(&ec2.DescribeImagesInput{ + Owners: []*string{aws.String("000000000000")}, + }, "000000000001") + require.NoError(t, err) + require.Len(t, result.Images, 1) + assert.Equal(t, "ami-sysfilter", *result.Images[0].ImageId) + assert.Equal(t, "000000000000", *result.Images[0].OwnerId) +} + func TestDescribeImages_NilInput(t *testing.T) { svc, _ := setupTestImageService(t)