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
8 changes: 8 additions & 0 deletions cmd/claws/imports_custom.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions custom/gamelift/builds/actions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package builds

import (
"context"
"fmt"

"github.com/aws/aws-sdk-go-v2/service/gamelift"

"github.com/clawscli/claws/internal/action"
appaws "github.com/clawscli/claws/internal/aws"
"github.com/clawscli/claws/internal/dao"
apperrors "github.com/clawscli/claws/internal/errors"
)

func init() {
action.Global.Register("gamelift", "builds", []action.Action{
{
Name: "Delete",
Shortcut: "D",
Type: action.ActionTypeAPI,
Operation: "DeleteBuild",
Confirm: action.ConfirmDangerous,
},
})

action.RegisterExecutor("gamelift", "builds", executeBuildAction)
}

func executeBuildAction(ctx context.Context, act action.Action, resource dao.Resource) action.ActionResult {
switch act.Operation {
case "DeleteBuild":
return executeDeleteBuild(ctx, resource)
default:
return action.UnknownOperationResult(act.Operation)
}
}

func executeDeleteBuild(ctx context.Context, resource dao.Resource) action.ActionResult {
build, ok := resource.(*BuildResource)
if !ok {
return action.InvalidResourceResult()
}

cfg, err := appaws.NewConfig(ctx)
if err != nil {
return action.ActionResult{Success: false, Error: apperrors.Wrap(err, "create gamelift client")}
}
client := gamelift.NewFromConfig(cfg)

buildId := build.GetID()
_, err = client.DeleteBuild(ctx, &gamelift.DeleteBuildInput{
BuildId: &buildId,
})
if err != nil {
return action.ActionResult{Success: false, Error: fmt.Errorf("delete build: %w", err)}
}

return action.ActionResult{
Success: true,
Message: fmt.Sprintf("Deleted build %s", build.GetName()),
}
}
7 changes: 7 additions & 0 deletions custom/gamelift/builds/constants.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

128 changes: 128 additions & 0 deletions custom/gamelift/builds/dao.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package builds

import (
"context"
"fmt"
"time"

"github.com/aws/aws-sdk-go-v2/service/gamelift"
"github.com/aws/aws-sdk-go-v2/service/gamelift/types"

appaws "github.com/clawscli/claws/internal/aws"
"github.com/clawscli/claws/internal/dao"
apperrors "github.com/clawscli/claws/internal/errors"
)

// BuildDAO provides data access for GameLift builds.
type BuildDAO struct {
dao.BaseDAO
client *gamelift.Client
}

// NewBuildDAO creates a new BuildDAO.
func NewBuildDAO(ctx context.Context) (dao.DAO, error) {
cfg, err := appaws.NewConfig(ctx)
if err != nil {
return nil, apperrors.Wrap(err, "new "+ServiceResourcePath+" dao")
}
return &BuildDAO{
BaseDAO: dao.NewBaseDAO("gamelift", "builds"),
client: gamelift.NewFromConfig(cfg),
}, nil
}

// List returns all GameLift builds.
func (d *BuildDAO) List(ctx context.Context) ([]dao.Resource, error) {
builds, err := appaws.Paginate(ctx, func(token *string) ([]types.Build, *string, error) {
output, err := d.client.ListBuilds(ctx, &gamelift.ListBuildsInput{
NextToken: token,
})
if err != nil {
return nil, nil, apperrors.Wrap(err, "list gamelift builds")
}
return output.Builds, output.NextToken, nil
})
if err != nil {
return nil, err
}

resources := make([]dao.Resource, len(builds))
for i, build := range builds {
resources[i] = NewBuildResource(build)
}
return resources, nil
}

// Get returns a specific GameLift build by ID.
func (d *BuildDAO) Get(ctx context.Context, id string) (dao.Resource, error) {
output, err := d.client.DescribeBuild(ctx, &gamelift.DescribeBuildInput{
BuildId: &id,
})
if err != nil {
return nil, apperrors.Wrapf(err, "describe gamelift build %s", id)
}
if output.Build == nil {
return nil, fmt.Errorf("gamelift build %s not found", id)
}
return NewBuildResource(*output.Build), nil
}

// Delete deletes a GameLift build by ID.
func (d *BuildDAO) Delete(ctx context.Context, id string) error {
_, err := d.client.DeleteBuild(ctx, &gamelift.DeleteBuildInput{
BuildId: &id,
})
if err != nil {
return apperrors.Wrapf(err, "delete gamelift build %s", id)
}
return nil
}

// BuildResource wraps a GameLift build.
type BuildResource struct {
dao.BaseResource
Build types.Build
}

// NewBuildResource creates a new BuildResource.
func NewBuildResource(build types.Build) *BuildResource {
return &BuildResource{
BaseResource: dao.BaseResource{
ID: appaws.Str(build.BuildId),
Name: appaws.Str(build.Name),
ARN: appaws.Str(build.BuildArn),
Data: build,
},
Build: build,
}
}

// Status returns the build status.
func (r *BuildResource) Status() string {
return string(r.Build.Status)
}

// Version returns the build version.
func (r *BuildResource) Version() string {
return appaws.Str(r.Build.Version)
}

// OperatingSystem returns the OS.
func (r *BuildResource) OperatingSystem() string {
return string(r.Build.OperatingSystem)
}

// SizeOnDisk returns the size in bytes.
func (r *BuildResource) SizeOnDisk() int64 {
return appaws.Int64(r.Build.SizeOnDisk)
}

// CreationTime returns when the build was created.
func (r *BuildResource) CreationTime() *time.Time {
return r.Build.CreationTime
}

// ServerSdkVersion returns the server SDK version.
func (r *BuildResource) ServerSdkVersion() string {
return appaws.Str(r.Build.ServerSdkVersion)
}
20 changes: 20 additions & 0 deletions custom/gamelift/builds/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package builds

import (
"context"

"github.com/clawscli/claws/internal/dao"
"github.com/clawscli/claws/internal/registry"
"github.com/clawscli/claws/internal/render"
)

func init() {
registry.Global.RegisterCustom("gamelift", "builds", registry.Entry{
DAOFactory: func(ctx context.Context) (dao.DAO, error) {
return NewBuildDAO(ctx)
},
RendererFactory: func() render.Renderer {
return NewBuildRenderer()
},
})
}
145 changes: 145 additions & 0 deletions custom/gamelift/builds/render.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package builds

import (
"fmt"

"github.com/clawscli/claws/internal/dao"
"github.com/clawscli/claws/internal/render"
)

// BuildRenderer renders GameLift builds.
type BuildRenderer struct {
render.BaseRenderer
}

// NewBuildRenderer creates a new BuildRenderer.
func NewBuildRenderer() render.Renderer {
return &BuildRenderer{
BaseRenderer: render.BaseRenderer{
Service: "gamelift",
Resource: "builds",
Cols: []render.Column{
{Name: "NAME", Width: 30, Getter: func(r dao.Resource) string { return r.GetName() }},
{Name: "BUILD ID", Width: 24, Getter: func(r dao.Resource) string { return r.GetID() }, Priority: 3},
{Name: "STATUS", Width: 14, Getter: getBuildStatus},
{Name: "VERSION", Width: 16, Getter: getBuildVersion},
{Name: "OS", Width: 16, Getter: getBuildOS},
{Name: "SIZE", Width: 12, Getter: getBuildSize, Priority: 2},
{Name: "SDK VERSION", Width: 14, Getter: getBuildSdkVersion, Priority: 3},
{Name: "CREATED", Width: 20, Getter: getBuildCreated, Priority: 2},
},
},
}
}

func getBuildStatus(r dao.Resource) string {
build, ok := r.(*BuildResource)
if !ok {
return ""
}
return build.Status()
}

func getBuildVersion(r dao.Resource) string {
build, ok := r.(*BuildResource)
if !ok {
return ""
}
return build.Version()
}

func getBuildOS(r dao.Resource) string {
build, ok := r.(*BuildResource)
if !ok {
return ""
}
return build.OperatingSystem()
}

func getBuildSize(r dao.Resource) string {
build, ok := r.(*BuildResource)
if !ok {
return ""
}
size := build.SizeOnDisk()
if size == 0 {
return "-"
}
return render.FormatSize(size)
}

func getBuildSdkVersion(r dao.Resource) string {
build, ok := r.(*BuildResource)
if !ok {
return ""
}
return build.ServerSdkVersion()
}

func getBuildCreated(r dao.Resource) string {
build, ok := r.(*BuildResource)
if !ok {
return ""
}
if t := build.CreationTime(); t != nil {
return t.Format("2006-01-02 15:04")
}
return ""
}

// RenderDetail renders the detail view for a GameLift build.
func (rr *BuildRenderer) RenderDetail(resource dao.Resource) string {
build, ok := resource.(*BuildResource)
if !ok {
return ""
}

d := render.NewDetailBuilder()

d.Title("GameLift Build", build.GetName())

d.Section("Basic Information")
d.Field("Name", build.GetName())
d.Field("Build ID", build.GetID())
d.Field("ARN", build.GetARN())
d.Field("Status", build.Status())

d.Section("Configuration")
if v := build.Version(); v != "" {
d.Field("Version", v)
}
d.Field("Operating System", build.OperatingSystem())
if v := build.ServerSdkVersion(); v != "" {
d.Field("Server SDK Version", v)
}

d.Section("Storage")
size := build.SizeOnDisk()
if size > 0 {
d.Field("Size on Disk", render.FormatSize(size))
} else {
d.Field("Size on Disk", fmt.Sprintf("%d bytes", size))
}

d.Section("Timestamps")
if t := build.CreationTime(); t != nil {
d.Field("Created", t.Format("2006-01-02 15:04:05"))
}

return d.String()
}

// RenderSummary renders summary fields for a GameLift build.
func (rr *BuildRenderer) RenderSummary(resource dao.Resource) []render.SummaryField {
build, ok := resource.(*BuildResource)
if !ok {
return rr.BaseRenderer.RenderSummary(resource)
}

return []render.SummaryField{
{Label: "Name", Value: build.GetName()},
{Label: "Build ID", Value: build.GetID()},
{Label: "Status", Value: build.Status()},
{Label: "Version", Value: build.Version()},
}
}
Loading
Loading