Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support service revision #309

Merged
merged 1 commit into from
Dec 29, 2024
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ tail -f /tmp/e1s.log
- [x] Auto refresh
- [x] Describe clusters
- [x] Describe services
- [x] Describe service deployments(new)
- [x] Describe service deployments
- [x] Describe service revisions
- [x] Describe tasks(running, stopped)
- [x] Describe containers
- [x] Describe task definitions
Expand Down
13 changes: 13 additions & 0 deletions internal/api/service_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,16 @@ func (store *Store) ListServiceDeployments(cluster, service *string) ([]types.Se

return describeOutput.ServiceDeployments, nil
}

// Equivalent to
// aws ecs describe-service-revisions --service-revision-arns ${arn1}
func (store *Store) GetServiceRevision(serviceRevisionArn *string) (*types.ServiceRevision, error) {
describeServiceRevisionOutput, err := store.ecs.DescribeServiceRevisions(context.Background(), &ecs.DescribeServiceRevisionsInput{
ServiceRevisionArns: []string{*serviceRevisionArn},
})
if err != nil {
slog.Warn("failed to run aws api to describe service revision", "error", err)
return nil, err
}
return &describeServiceRevisionOutput.ServiceRevisions[0], nil
}
3 changes: 2 additions & 1 deletion internal/view/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Entity struct {
metrics *api.MetricsData
autoScaling *api.AutoScalingData
serviceDeployment *types.ServiceDeployment
serviceRevision *types.ServiceRevision
entityName string
}

Expand Down Expand Up @@ -282,7 +283,7 @@ func (app *App) showPrimaryKindPage(k kind, reload bool) error {
err = app.showContainersPage(reload)
case TaskDefinitionKind:
err = app.showTaskDefinitionPage(reload)
case ServiceDeployment:
case ServiceDeploymentKind:
err = app.showServiceDeploymentPage(reload)
default:
app.kind = ClusterKind
Expand Down
4 changes: 2 additions & 2 deletions internal/view/footer.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func newFooter() *footer {
task: tview.NewTextView().SetDynamicColors(true).SetText(fmt.Sprintf(color.FooterItemFmt, TaskKind)),
container: tview.NewTextView().SetDynamicColors(true).SetText(fmt.Sprintf(color.FooterItemFmt, ContainerKind)),
taskDefinition: tview.NewTextView().SetDynamicColors(true).SetText(fmt.Sprintf(color.FooterItemFmt, TaskDefinitionKind)).SetTextAlign(L),
serviceDeployment: tview.NewTextView().SetDynamicColors(true).SetText(fmt.Sprintf(color.FooterItemFmt, ServiceDeployment)).SetTextAlign(L),
serviceDeployment: tview.NewTextView().SetDynamicColors(true).SetText(fmt.Sprintf(color.FooterItemFmt, ServiceDeploymentKind)).SetTextAlign(L),
help: tview.NewTextView().SetDynamicColors(true).SetText(fmt.Sprintf(color.FooterItemFmt, HelpKind)).SetTextAlign(L),
}
}
Expand All @@ -46,7 +46,7 @@ func (v *view) addFooterItems() {
v.footer.footerFlex.
AddItem(tview.NewTextView(), 5, 0, false).
AddItem(v.footer.taskDefinition, 0, 1, false)
} else if v.app.kind == ServiceDeployment {
} else if v.app.kind == ServiceDeploymentKind {
v.footer.footerFlex.
AddItem(tview.NewTextView(), 5, 0, false).
AddItem(v.footer.serviceDeployment, 0, 1, false)
Expand Down
7 changes: 4 additions & 3 deletions internal/view/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ const (

var hotKeyMap = map[string]keyDescriptionPair{
"/": {key: "/", description: "Search in table"},
"a": {key: "a", description: "Describe service auto scaling"},
"a": {key: "a", description: "Show service auto scaling"},
"f": {key: "f", description: "Toggle full screen"},
"l": {key: "l", description: "Show cloudwatch logs(Only support awslogs logDriver)"},
"m": {key: "m", description: "Show metrics(CPU/Memory)"},
"r": {key: "r", description: "Realtime log streaming(Only support one log group)"},
"t": {key: "t", description: "Show task definitions"},
"p": {key: "t", description: "Show service deployments"},
"p": {key: "p", description: "Show service deployments"},
"n": {key: "n", description: "Show all cluster tasks"},
"s": {key: "s", description: "Toggle running/stopped tasks"},
"w": {key: "w", description: "Describe service events"},
"w": {key: "w", description: "Show service events"},
"v": {key: "v", description: "Show service revision"},
"S": {key: "shift-s", description: "Stop task"},
"P": {key: "shift-p", description: "Transfer file though a S3 bucket"},
"D": {key: "shift-d", description: "Download text file content(beta)"},
Expand Down
25 changes: 24 additions & 1 deletion internal/view/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,27 @@ func (v *view) switchToAutoScalingJson() {
v.showJsonPages(entity)
}

// Switch to service revision
func (v *view) switchToServiceRevisionJson() {
selected, err := v.getCurrentSelection()
if err != nil {
return
}
serviceRevisionArn := selected.serviceDeployment.TargetServiceRevision.Arn

if serviceRevisionArn == nil {
return
}

serviceRevision, err := v.app.Store.GetServiceRevision(serviceRevisionArn)

if err != nil {
return
}
entity := Entity{serviceRevision: serviceRevision, entityName: *selected.serviceDeployment.ServiceDeploymentArn}
v.showJsonPages(entity)
}

// Show new page from JSON content in table area and handle done event to go back
func (v *view) showJsonPages(entity Entity) {
colorizedJsonString, rawJsonString, err := v.getJsonString(entity)
Expand Down Expand Up @@ -218,7 +239,7 @@ func (v *view) getJsonString(entity Entity) (string, []byte, error) {
data = entity.events
case entity.service != nil && v.app.kind == ServiceKind:
data = entity.service
case entity.serviceDeployment != nil && v.app.kind == ServiceDeployment:
case entity.serviceDeployment != nil && v.app.kind == ServiceDeploymentKind:
data = entity.serviceDeployment
case entity.task != nil && v.app.kind == TaskKind:
data = entity.task
Expand All @@ -230,6 +251,8 @@ func (v *view) getJsonString(entity Entity) (string, []byte, error) {
data = entity.metrics
case entity.autoScaling != nil:
data = entity.autoScaling
case entity.serviceRevision != nil:
data = entity.serviceRevision
default:
slog.Error("failed to get json string", "data", data)
data = struct {
Expand Down
11 changes: 7 additions & 4 deletions internal/view/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ const (
HelpKind
DescriptionKind
ServiceEventsKind
ServiceDeployment
ServiceDeploymentKind
LogKind
AutoScalingKind
ServiceRevisionKind
ModalKind
EmptyKind
)
Expand All @@ -36,8 +37,10 @@ func (k kind) String() string {
return "task definitions"
case ServiceEventsKind:
return "service events"
case ServiceDeployment:
case ServiceDeploymentKind:
return "service deployments"
case ServiceRevisionKind:
return "service revision"
case LogKind:
return "logs"
case AutoScalingKind:
Expand Down Expand Up @@ -68,7 +71,7 @@ func (k kind) prevKind() kind {
return ClusterKind
case ServiceKind:
return ClusterKind
case TaskKind, TaskDefinitionKind, ServiceDeployment:
case TaskKind, TaskDefinitionKind, ServiceDeploymentKind:
return ServiceKind
case ContainerKind:
return TaskKind
Expand All @@ -82,7 +85,7 @@ func (k kind) getAppPageName(name string) string {
switch k {
case ClusterKind:
return k.String()
case ServiceKind, TaskKind, ContainerKind, TaskDefinitionKind, ServiceDeployment, DescriptionKind:
case ServiceKind, TaskKind, ContainerKind, TaskDefinitionKind, ServiceDeploymentKind, DescriptionKind:
return k.String() + "." + name
default:
return k.String()
Expand Down
36 changes: 18 additions & 18 deletions internal/view/service_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ type serviceDeploymentView struct {
// Constructor for service deployment view
func newServiceDeploymentView(serviceDeployments []types.ServiceDeployment, app *App) *serviceDeploymentView {
keys := append(basicKeyInputs, []keyDescriptionPair{
hotKeyMap["U"],
hotKeyMap["v"],
}...)
return &serviceDeploymentView{
view: *newView(app, keys, secondaryPageKeyMap{
DescriptionKind: describePageKeys,
DescriptionKind: describePageKeys,
ServiceRevisionKind: describePageKeys,
}),
serviceDeployments: serviceDeployments,
}
Expand Down Expand Up @@ -91,8 +92,8 @@ func (v *serviceDeploymentView) headerPagesParam(d types.ServiceDeployment) (ite
return "-"
}
return fmt.Sprintf("Max: %d%%, Min: %d%%",
d.DeploymentConfiguration.MaximumPercent,
d.DeploymentConfiguration.MinimumHealthyPercent)
*d.DeploymentConfiguration.MaximumPercent,
*d.DeploymentConfiguration.MinimumHealthyPercent)
}()},
{name: "Circuit Breaker Config", value: func() string {
if d.DeploymentConfiguration == nil || d.DeploymentConfiguration.DeploymentCircuitBreaker == nil {
Expand All @@ -102,24 +103,23 @@ func (v *serviceDeploymentView) headerPagesParam(d types.ServiceDeployment) (ite
d.DeploymentConfiguration.DeploymentCircuitBreaker.Enable,
d.DeploymentConfiguration.DeploymentCircuitBreaker.Rollback)
}()},
{name: "Source revision", value: func() string {
if len(d.SourceServiceRevisions) == 0 {
{name: "Target task count", value: func() string {
if d.TargetServiceRevision == nil {
return "-"
}
return fmt.Sprintf("%s (Running: %d, Pending: %d)",
utils.ArnToName(d.SourceServiceRevisions[0].Arn),
d.SourceServiceRevisions[0].RunningTaskCount,
d.SourceServiceRevisions[0].PendingTaskCount)
return fmt.Sprintf("Requested: %d, Running: %d, Pending: %d",
d.TargetServiceRevision.RequestedTaskCount,
d.TargetServiceRevision.RunningTaskCount,
d.TargetServiceRevision.PendingTaskCount)
}()},
{name: "Target revision", value: func() string {
if d.TargetServiceRevision == nil {
{name: "Source task count", value: func() string {
if len(d.SourceServiceRevisions) == 0 {
return "-"
}
return fmt.Sprintf("%s (Running: %d, Pending: %d, Requested: %d)",
utils.ArnToName(d.TargetServiceRevision.Arn),
d.TargetServiceRevision.RunningTaskCount,
d.TargetServiceRevision.PendingTaskCount,
d.TargetServiceRevision.RequestedTaskCount)
return fmt.Sprintf("Requested: %d, Running: %d, Pending: %d",
d.SourceServiceRevisions[0].RequestedTaskCount,
d.SourceServiceRevisions[0].RunningTaskCount,
d.SourceServiceRevisions[0].PendingTaskCount)
}()},
{name: "Created At", value: utils.ShowTime(d.CreatedAt)},
{name: "Started At", value: utils.ShowTime(d.StartedAt)},
Expand Down Expand Up @@ -163,7 +163,7 @@ func (v *serviceDeploymentView) tableParam() (title string, headers []string, da
headers = []string{
"Deployment ID ▾",
"Status",
"Revision",
"Target service revision",
"Created At",
"Started At",
"Finished At",
Expand Down
12 changes: 9 additions & 3 deletions internal/view/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,13 @@ func (v *view) handleInputCapture(event *tcell.EventKey) *tcell.EventKey {
}
case 'p':
if v.app.kind == ServiceKind {
v.showKindPage(ServiceDeployment, false)
v.showKindPage(ServiceDeploymentKind, false)
return event
}
case 'v':
if v.app.kind == ServiceDeploymentKind {
v.app.secondaryKind = ServiceRevisionKind
v.showSecondaryKindPage(false)
return event
}
case 's':
Expand Down Expand Up @@ -284,7 +290,7 @@ func (v *view) changeSelectedValues() {
slog.Warn("unexpected in changeSelectedValues", "kind", v.app.kind)
return
}
case ServiceDeployment:
case ServiceDeploymentKind:
serviceDeployment := selected.serviceDeployment
if serviceDeployment != nil {
v.app.serviceDeployment = selected.serviceDeployment
Expand Down Expand Up @@ -320,7 +326,7 @@ func (v *view) openInBrowser() {
arn = *v.app.task.TaskArn
case TaskDefinitionKind:
arn = *v.app.taskDefinition.TaskDefinitionArn
case ServiceDeployment:
case ServiceDeploymentKind:
arn = *v.app.serviceDeployment.ServiceDeploymentArn
}
url := utils.ArnToUrl(arn, taskService)
Expand Down
4 changes: 3 additions & 1 deletion internal/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ func (v *view) showSecondaryKindPage(reload bool) {
v.switchToLogsList()
case ServiceEventsKind:
v.switchToServiceEventsList()
case ServiceRevisionKind:
v.switchToServiceRevisionJson()
}
if !reload {
v.app.Notice.Infof("Viewing %s...", v.app.secondaryKind.String())
Expand Down Expand Up @@ -158,7 +160,7 @@ func (v *view) handleSecondaryPageSwitch(entity Entity, colorizedJsonString stri
v.realtimeAwsLog(entity)
}
case 'e':
if v.app.secondaryKind == DescriptionKind || v.app.secondaryKind == AutoScalingKind || v.app.secondaryKind == LogKind {
if v.app.secondaryKind == DescriptionKind || v.app.secondaryKind == AutoScalingKind || v.app.secondaryKind == ServiceRevisionKind || v.app.secondaryKind == LogKind {
v.openInEditor(jsonBytes)
}
}
Expand Down
Loading