Add Topology CLI: net can-connect / trace (#335 P2) - #340
Merged
Conversation
Surface the network-reachability engine so users can check, locally, whether their security groups, routes, and peering actually let one instance reach another — a capability no other local cloud emulator has. - serve: builds the AWS topology engine (EC2/VPC/Route53) in rebuild() and serves GET /_cloudemu/net/can-connect and /net/trace; admin.NewControl gains an optional extra handler that these routes plug into. - CLI: `cloudemu net can-connect <A> <B> [--port] [--protocol]` and `net trace <A> <destIP>`, with human output or --json. - EC2: wire RunInstances to resolve an instance's VPC from its --subnet-id (mirrors the existing RDS SubnetResolver), so instances created via the API carry the VPCID that reachability analysis and trace depend on. Without this the feature only works for in-process setups, not the aws CLI / Terraform. AWS-only (VPC/SG/route concepts). Note: cloudemu security groups have no implicit allow-all egress, so can-connect needs an explicit egress rule.
NitinKumar004
approved these changes
Aug 8, 2026
NitinKumar004
left a comment
Collaborator
There was a problem hiding this comment.
Approving — topology CLI
Deep-reviewed in an isolated worktree at the PR head; gate green (build + GOOS=windows go build ./cmd/cloudemu / vet / go test -race ./providers/aws/ec2/... ./providers/aws/vpc/... ./features/topology/... ./server/admin/... ./cmd/cloudemu/... ok all / gofmt clean).
What stood out:
- The EC2 subnet→VPC resolver is the right fix and follows the existing
RDS/ElastiCacheSetSubnetResolverpattern. Blast radius is small and I checked it:VPCIDwas already aninstanceDatafield (already surfaced byDescribeInstances), andDeleteVPCgates on attached ENIs — not instances-by-VPCID (separate mocks) — so teardown behavior is unchanged. Populating it just feeds the topology engine +vpc-idfiltering, which is strictly more correct and is what makes the feature usable through the real CLI/Terraform. - admin
extrahandler — clean delegation of unknown/_cloudemu/*paths, nil-safe (→404), only mounted when--admin. Tested. netEngineconcurrency is correct — read underrebuildMu, written under the same lock inrebuild(), and the query runs on the localengoutside the lock, matching the established seed/snapshot convention. No race.- net CLI — good validation, sensible defaults (port 0 / protocol tcp), reuses the established daemon-down/admin-off/timeout helpers with clean status→error mapping; endpoints are read-only.
- Mirror rule — aws-only, explicitly scoped (GCP/Azure topology is a documented follow-up).
One non-blocking Low: gosec flags G704 "SSRF via taint" on net.go:184,189, but this is a local CLI calling its own daemon (URL from our own endpoints file + a hardcoded path) — no attacker-controlled destination. Same newer-gosec version drift as the earlier findings; a //nolint:gosec documents it if your pinned linter ever surfaces it.
Clean, well-scoped feature with a correct wire fix. LGTM.
…to feat/topology-cli # Conflicts: # cmd/cloudemu/serve.go # docs/standalone-server.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective / Issue
First P2 differentiator of the "minikube for cloud resources" roadmap (#335). cloudemu already has a network-reachability engine (
features/topology:CanConnect/TraceRoute) that evaluates security groups, routes, NACLs, and VPC peering — but nothing exposed it. This surfaces it as a CLI so users can check, locally, whether one instance can actually reach another. No other local emulator (LocalStack, moto, minikube) does network reachability.What we found
SubnetIdbut noVpcId— so topology saw every instance in one empty VPC (can-connecttrivially "same VPC",tracefailed "no route table for VPC "). The feature would only work for in-process setups, not theawsCLI / Terraform workflow it's meant for.How we fixed it / How it works
EC2/VPC/Route53) inrebuild()and servesGET /_cloudemu/net/can-connectand/net/trace.admin.NewControlgains an optionalextrahandler these routes plug into (unknown/_cloudemu/*→ extra, else 404).cloudemu net can-connect <A> <B> [--port] [--protocol]andnet trace <A> <destIP>, human output or--json; clear errors for daemon-down /--admin=false/ aws-not-running / instance-not-found.RunInstancesnow resolves an instance's VPC from its--subnet-id(mirrors the existing RDSSubnetResolver), wired viap.EC2.SetSubnetResolver(p.VPC). This is what makes the feature usable through Terraform / the aws CLI.sequenceDiagram actor U as You participant CLI as cloudemu net participant S as serve (daemon) participant E as topology engine U->>CLI: net can-connect i-web i-db --port 5432 CLI->>S: GET /_cloudemu/net/can-connect?from&to&port S->>E: CanConnect (VPC reachability, SG egress+ingress) E-->>S: Allowed? + reason + path S-->>U: YES/NO + hop pathAlternatives not taken
vpctest enshrines the no-default-egress model, so changing it is out of scope; documented instead.Docs / Tests / Playground
docs/standalone-server.md— network-reachability section (usage, aws-only, egress nuance,--subnet-idnote).extradelegation; net handler validation/error paths; EC2 subnet→VPC resolver round-trip; net CLI helpers. Engine itself already thoroughly tested.Test plan
go test -race ./providers/aws/ec2/... ./features/topology/... ./server/admin/... ./cmd/cloudemu/...GOOS=windows) / vet /go test ./.../ tidy / golangci-lint = clean (CodeQL: only pre-existing findings, none in changed files).cloudemu start+ realawsCLI on default~/.cloudemu: create VPC/subnet/2 SGs/2 instances →can-connectNO (with blocking reason) → open web egress + db ingress → YES + hop path →traceshows route-table/local hops →--jsonworks.Risk & Rollback
--admin+ the aws provider. The EC2 resolver only sets a previously-empty field (more correct, matches AWS). Rollback = revert.Conclusion
cloudemu net can-connect/traceanswers "will my security groups and routes actually let A reach B?" locally — the standout capability no competitor offers.Follow-ups (#335): GCP/Azure topology; a default-egress fidelity toggle; more P2 items (cost preview, IAM enforcement, MCP server).