From 1a8386bc7c364b13b39f51999cf8547bd925bbb3 Mon Sep 17 00:00:00 2001 From: Ed Smith Date: Fri, 11 Oct 2024 20:43:14 +0100 Subject: [PATCH] chore: move around and rename some files (#52) --- internal/app.go | 66 ++++++++++++++++----- internal/{internal.go => aws.go} | 68 +++++----------------- internal/{internal_test.go => aws_test.go} | 0 internal/command.go | 4 +- internal/forward.go | 5 +- internal/select.go | 10 +++- 6 files changed, 78 insertions(+), 75 deletions(-) rename internal/{internal.go => aws.go} (73%) rename internal/{internal_test.go => aws_test.go} (100%) diff --git a/internal/app.go b/internal/app.go index 918f96c..1dc2e29 100644 --- a/internal/app.go +++ b/internal/app.go @@ -1,35 +1,72 @@ +/* app.go contains the main logic for running the app */ + package app import ( "context" "errors" + "flag" "fmt" + "os" "os/exec" + "os/signal" "sort" "strings" + "syscall" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ecs" ecsTypes "github.com/aws/aws-sdk-go-v2/service/ecs/types" + "github.com/fatih/color" "github.com/spf13/viper" ) -type EC2Client interface { - DescribeInstances(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeInstancesOutput, error) -} +var ( + region string + + Red = color.New(color.FgRed).SprintFunc() + Magenta = color.New(color.FgMagenta).SprintFunc() + Cyan = color.New(color.FgCyan).SprintFunc() + Green = color.New(color.FgGreen).SprintFunc() + Yellow = color.New(color.FgYellow).SprintFunc() + + pageSize = 15 + backOpt = "⏎ Back" // backOpt is used to allow the user to navigate backwards in the selection prompt + awsMaxResults = aws.Int32(int32(100)) +) + +// runCommand executes a command in the current shell and returns an error if the command fails +func runCommand(process string, args ...string) error { + if flag.Lookup("test.v") != nil { + // emulate successful return for testing purposes + return nil + } + + // Capture any SIGINTs and discard them + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, os.Interrupt, syscall.SIGINT) + go func() { + for { + select { + case <-sigs: + } + } + }() + defer close(sigs) + + cmd := exec.Command(process, args...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + cmd.Stdin = os.Stdin -type ECSClient interface { - ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error) - ListServices(ctx context.Context, params *ecs.ListServicesInput, optFns ...func(*ecs.Options)) (*ecs.ListServicesOutput, error) - ListTasks(ctx context.Context, params *ecs.ListTasksInput, optFns ...func(*ecs.Options)) (*ecs.ListTasksOutput, error) - DescribeTasks(ctx context.Context, params *ecs.DescribeTasksInput, optFns ...func(*ecs.Options)) (*ecs.DescribeTasksOutput, error) - DescribeTaskDefinition(ctx context.Context, params *ecs.DescribeTaskDefinitionInput, optFns ...func(*ecs.Options)) (*ecs.DescribeTaskDefinitionOutput, error) - DescribeContainerInstances(ctx context.Context, params *ecs.DescribeContainerInstancesInput, optFns ...func(*ecs.Options)) (*ecs.DescribeContainerInstancesOutput, error) - ExecuteCommand(ctx context.Context, params *ecs.ExecuteCommandInput, optFns ...func(*ecs.Options)) (*ecs.ExecuteCommandOutput, error) + if err := cmd.Run(); err != nil { + return err + } + + return nil } -// App is a struct that contains information about our command state +// App is the main struct for the application which holds the state and methods for the application type App struct { input chan string err chan error @@ -127,7 +164,6 @@ func (e *App) getCluster() { } if e.client == nil { - panic("oh no") } list, err := e.client.ListClusters(context.TODO(), &ecs.ListClustersInput{ @@ -445,7 +481,7 @@ func (e *App) getContainerOS() { // if the OperatingSystemFamily has not been specified in the task definition // then we refer to the container instance to determine the OS if family == "" { - ec2Client := createEc2Client() + ec2Client := createEC2Client() family, err = getContainerInstanceOS(e.client, ec2Client, e.cluster, *e.task.ContainerInstanceArn) if err != nil { e.err <- err diff --git a/internal/internal.go b/internal/aws.go similarity index 73% rename from internal/internal.go rename to internal/aws.go index f55a69e..8d7b32a 100644 --- a/internal/internal.go +++ b/internal/aws.go @@ -1,12 +1,9 @@ +/* aws.go contains AWS Client creation funcs and other helpers used by the main app */ + package app import ( "context" - "flag" - "os" - "os/exec" - "os/signal" - "syscall" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -15,27 +12,21 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ecs" ecsTypes "github.com/aws/aws-sdk-go-v2/service/ecs/types" - "github.com/fatih/color" "github.com/spf13/viper" ) -var ( - region string - - Red = color.New(color.FgRed).SprintFunc() - Magenta = color.New(color.FgMagenta).SprintFunc() - Cyan = color.New(color.FgCyan).SprintFunc() - Green = color.New(color.FgGreen).SprintFunc() - Yellow = color.New(color.FgYellow).SprintFunc() - - pageSize = 15 - backOpt = "⏎ Back" // backOpt is used to allow the user to navigate backwards in the selection prompt - awsMaxResults = aws.Int32(int32(100)) -) +type EC2Client interface { + DescribeInstances(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeInstancesOutput, error) +} -func createOpts(opts []string) []string { - initialOpts := []string{backOpt} - return append(initialOpts, opts...) +type ECSClient interface { + ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error) + ListServices(ctx context.Context, params *ecs.ListServicesInput, optFns ...func(*ecs.Options)) (*ecs.ListServicesOutput, error) + ListTasks(ctx context.Context, params *ecs.ListTasksInput, optFns ...func(*ecs.Options)) (*ecs.ListTasksOutput, error) + DescribeTasks(ctx context.Context, params *ecs.DescribeTasksInput, optFns ...func(*ecs.Options)) (*ecs.DescribeTasksOutput, error) + DescribeTaskDefinition(ctx context.Context, params *ecs.DescribeTaskDefinitionInput, optFns ...func(*ecs.Options)) (*ecs.DescribeTaskDefinitionOutput, error) + DescribeContainerInstances(ctx context.Context, params *ecs.DescribeContainerInstancesInput, optFns ...func(*ecs.Options)) (*ecs.DescribeContainerInstancesOutput, error) + ExecuteCommand(ctx context.Context, params *ecs.ExecuteCommandInput, optFns ...func(*ecs.Options)) (*ecs.ExecuteCommandOutput, error) } func createEcsClient() *ecs.Client { @@ -61,7 +52,7 @@ func createEcsClient() *ecs.Client { return client } -func createEc2Client() *ec2.Client { +func createEC2Client() *ec2.Client { region := viper.GetString("region") getCustomAWSEndpoint := func(o *ec2.Options) { endpointUrl := viper.GetString("aws-endpoint-url") @@ -121,37 +112,6 @@ func getContainerInstanceOS(ecsClient ECSClient, ec2Client EC2Client, cluster st return operatingSystem, nil } -// runCommand executes a command with args -func runCommand(process string, args ...string) error { - if flag.Lookup("test.v") != nil { - // emulate successful return for testing purposes - return nil - } - - // Capture any SIGINTs and discard them - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, os.Interrupt, syscall.SIGINT) - go func() { - for { - select { - case <-sigs: - } - } - }() - defer close(sigs) - - cmd := exec.Command(process, args...) - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - cmd.Stdin = os.Stdin - - if err := cmd.Run(); err != nil { - return err - } - - return nil -} - func getContainerPort(client ECSClient, taskDefinitionArn string, containerName string) (*int32, error) { res, err := client.DescribeTaskDefinition(context.TODO(), &ecs.DescribeTaskDefinitionInput{ TaskDefinition: aws.String(taskDefinitionArn), diff --git a/internal/internal_test.go b/internal/aws_test.go similarity index 100% rename from internal/internal_test.go rename to internal/aws_test.go diff --git a/internal/command.go b/internal/command.go index f732dc8..2074d9e 100644 --- a/internal/command.go +++ b/internal/command.go @@ -12,8 +12,8 @@ import ( "github.com/spf13/viper" ) -// executeCommand takes all of our previous values and builds a session for us -// and then calls runCommand to execute the session input via session-manager-plugin +// executeCommand takes the app state and builds an execute-command session for us +// which is then passed to the session-manager-plugin for execution func (e *App) executeCommand() error { var command string if viper.GetString("cmd") != "" { diff --git a/internal/forward.go b/internal/forward.go index 264c542..53565f2 100644 --- a/internal/forward.go +++ b/internal/forward.go @@ -13,8 +13,8 @@ import ( "github.com/spf13/viper" ) -// executeInput takes all of our previous values and builds a session for us -// and then calls runCommand to execute the session input via session-manager-plugin +// executeForward takes the app state and builds a port-forward session for us +// which is then passed to the session-manager-plugin for execution func (e *App) executeForward() error { taskArnSplit := strings.Split(*e.task.TaskArn, "/") taskID := taskArnSplit[len(taskArnSplit)-1] @@ -79,5 +79,4 @@ func (e *App) executeForward() error { err = runCommand("session-manager-plugin", string(sessJson), e.region, "StartSession", "", string(paramsJson)) e.err <- err return err - } diff --git a/internal/select.go b/internal/select.go index 475c306..51da738 100644 --- a/internal/select.go +++ b/internal/select.go @@ -1,3 +1,5 @@ +/* select.go contains the logic for the Select/Survey views in the TUI app */ + package app import ( @@ -7,7 +9,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/aws/aws-sdk-go-v2/aws" - // "github.com/aws/aws-sdk-go-v2/service/ecs" + ecsTypes "github.com/aws/aws-sdk-go-v2/service/ecs/types" ) @@ -27,6 +29,12 @@ func init() { {{- end}}` } +// createOpts builds the initial options for the survey prompts +func createOpts(opts []string) []string { + initialOpts := []string{backOpt} + return append(initialOpts, opts...) +} + // selectCluster provides the prompt for choosing a cluster func selectCluster(clusterNames []string) (string, error) { if flag.Lookup("test.v") != nil {