Now I have a clear understanding of the patterns. Let me present my plan:
Plan for mysql-conn Command
Overview
Create a new command mysql-conn under pkg/cmd/mysqlconn/ that follows the same patterns as the ctx command.
Implementation Steps
- Create
pkg/cmd/mysqlconn/mysqlconn.gowith: MySQLConnOptionsstruct embedding*types.OptionsNewCmdMySQLConn()factory function-
Flag for
--port(default: 13306) -
Core Logic Flow:
- Extract
envfromAWS_PROFILE(e.g.,dev-imprint-admin→dev) - Run
aws ssm list-documentsto get available SSM documents - Parse document names to extract
db_namefrom pattern{env}-imprint-forward-{db_name}-mysql-db - Show interactive selection using
promptui.Select(same asctx) - Get bastion instance ID via
aws ec2 describe-instances -
Find unused port and start SSM session
-
Unused Port Detection (Most Efficient Method):
The most efficient approach is to let the OS assign a free port using Go's net package:
go
func findUnusedPort(preferredPort int) (int, error) {
// Try preferred port first
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", preferredPort))
if err == nil {
ln.Close()
return preferredPort, nil
}
// Let OS assign a free port
ln, err = net.Listen("tcp", ":0")
if err != nil {
return 0, err
}
port := ln.Addr().(*net.TCPAddr).Port
ln.Close()
return port, nil
}
This is more efficient than scanning ports because: - Single syscall to OS to check/assign port - No race conditions (OS handles atomicity) - Falls back gracefully if preferred port is busy
- Register in
pkg/cmd/root.go: - Import
mysqlconnpackage -
Add
cmd.AddCommand(mysqlconn.NewCmdMySQLConn(opts)) -
Tests in
pkg/cmd/mysqlconn/mysqlconn_test.go: - Table-driven tests for env extraction
- Test document name parsing
- Test port finding logic
- Mock AWS CLI calls for unit tests
Files to Create/Modify
| File | Action |
|---|---|
pkg/cmd/mysqlconn/mysqlconn.go |
Create |
pkg/cmd/mysqlconn/mysqlconn_test.go |
Create |
pkg/cmd/root.go |
Modify (add import + registration) |
Questions Before Implementation
-
Env extraction: Should I extract env as the first segment before
-imprint? (e.g.,dev-imprint-admin→dev,staging-imprint-admin→staging) -
Error handling: If no SSM documents are found, should it show an error or gracefully exit?
-
Port behavior: Should the command print the port being used (to stderr) so users know where to connect?
Do you approve this plan? Any changes you'd like before I implement?