Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/dist/
/unic
.claude/reports/
# SSM session-manager-plugin temp files (ecs exec session state)
cs.json
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ Behavior:
| IAM | IAM User Browser (lightweight username pages, background filter expansion, detail drill-down) | ✅ Implemented |
| IAM | Access Key Browser (list keys with status, age, last used) | ✅ Implemented |
| IAM | Access Key Rotation (create → verify/apply → deactivate → delete) | ✅ Implemented |
| ECS | ECS Exec Sessions (Clusters → Services → Tasks → Containers, exec session via `aws ecs execute-command`) | ✅ Implemented |

## TUI Key Bindings

Expand Down Expand Up @@ -243,6 +244,16 @@ Behavior:
| `n` | Load more (older events) | Viewer |
| `PgUp`/`PgDn` | Page scroll | Viewer |

### ECS Exec Sessions

| Key | Action | Screen |
|-----|--------|--------|
| `/` | Filter clusters/services | Cluster / Service list |
| `r` | Refresh list | Cluster / Service / Task list |
| `Enter` | Drill down (Cluster → Service → Task → Container) | Any list |
| `Enter` | Start exec session (`/bin/sh`) | Container list |
| `Esc` | Go back one level | Any screen |

### Context Switcher

| Key | Action |
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.68.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ecs v1.76.0 // indirect
github.com/aws/aws-sdk-go-v2/service/iam v1.53.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.68.0 h1:+/lmB/+i2oqkzbmlQ
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.68.0/go.mod h1:PobeppEnIjw4pcgjFryNDZCTH7AiqZw0yb5r98Gvf9c=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0 h1:98Miqj16un1WLNyM1RjVDhXYumhqZrQfAeG8i4jPG6o=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0/go.mod h1:T6ndRfdhnXLIY5oKBHjYZDVj706los2zGdpThppquvA=
github.com/aws/aws-sdk-go-v2/service/ecs v1.76.0 h1:a5G/TgJNrpuCjZBTf8/PTN0C2B0do/ylaYVynxPSbUQ=
github.com/aws/aws-sdk-go-v2/service/ecs v1.76.0/go.mod h1:QkWmubOYmjj3cHn7A4CoUU7BKJhVeo39Gp6NH7IyhZw=
github.com/aws/aws-sdk-go-v2/service/iam v1.53.7 h1:n9YLiWtX3+6pTLZWvRJmtq5JIB9NA/KFelyCg5fOlTU=
github.com/aws/aws-sdk-go-v2/service/iam v1.53.7/go.mod h1:sP46Vo6MeJcM4s0ZXcG2PFmfiSyixhIuC/74W52yKuk=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
Expand Down
46 changes: 46 additions & 0 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const (
screenCWLogGroupList
screenCWLogStreamList
screenCWLogViewer
screenECSClusterList
screenECSServiceList
screenECSTaskList
screenECSContainerList
screenS3BucketList
screenS3ObjectList
screenS3ObjectDetail
Expand Down Expand Up @@ -179,6 +183,28 @@ type Model struct {
sgAddInput string // current field text input
sgAddSelectIdx int // index for select-type fields (direction, protocol)

// ECS browser state
ecsClusters []awsservice.ECSCluster
filteredECSClusters []awsservice.ECSCluster
ecsClusterIdx int
ecsClusterFilter string
ecsClusterFilterActive bool
selectedECSCluster *awsservice.ECSCluster

ecsServices []awsservice.ECSService
filteredECSServices []awsservice.ECSService
ecsServiceIdx int
ecsServiceFilter string
ecsServiceFilterActive bool
selectedECSService *awsservice.ECSService

ecsTasks []awsservice.ECSTask
ecsTaskIdx int
selectedECSTask *awsservice.ECSTask

ecsContainers []awsservice.ECSContainer
ecsContainerIdx int

// CloudWatch Logs browser state
cwLogGroups []awsservice.LogGroup
filteredCWLogGroups []awsservice.LogGroup
Expand Down Expand Up @@ -329,6 +355,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.handleIAMMsg,
m.handleSecretMsg,
m.handleCloudWatchLogsMsg,
m.handleECSMsg,
m.handleS3Msg,
m.handleContextMsg,
} {
Expand Down Expand Up @@ -424,6 +451,14 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m.updateIAMKeyRotateConfirm(msg)
case screenIAMKeyRotateResult:
return m.updateIAMKeyRotateResult(msg)
case screenECSClusterList:
return m.updateECSClusterList(msg)
case screenECSServiceList:
return m.updateECSServiceList(msg)
case screenECSTaskList:
return m.updateECSTaskList(msg)
case screenECSContainerList:
return m.updateECSContainerList(msg)
case screenContextPicker:
return m.updateContextPicker(msg)
case screenContextAdd:
Expand Down Expand Up @@ -530,6 +565,9 @@ func (m Model) updateFeatureList(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
m.iamRotationEnabled = true
m.screen = screenLoading
return m, m.loadIAMKeys()
case domain.FeatureECSExec:
m.screen = screenLoading
return m, m.loadECSClusters()
}
}
}
Expand Down Expand Up @@ -621,6 +659,14 @@ func (m Model) View() string {
v = m.viewIAMKeyRotateConfirm()
case screenIAMKeyRotateResult:
v = m.viewIAMKeyRotateResult()
case screenECSClusterList:
v = m.viewECSClusterList()
case screenECSServiceList:
v = m.viewECSServiceList()
case screenECSTaskList:
v = m.viewECSTaskList()
case screenECSContainerList:
v = m.viewECSContainerList()
case screenContextPicker:
v = m.viewContextPicker()
case screenContextAdd:
Expand Down
20 changes: 20 additions & 0 deletions internal/app/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,23 @@ type iamKeyDeletedMsg struct {
keyID string
err error
}

type ecsClustersLoadedMsg struct {
clusters []awsservice.ECSCluster
}

type ecsServicesLoadedMsg struct {
services []awsservice.ECSService
}

type ecsTasksLoadedMsg struct {
tasks []awsservice.ECSTask
}

type ecsContainersLoadedMsg struct {
containers []awsservice.ECSContainer
}

type ecsExecDoneMsg struct {
err error
}
Loading
Loading