Skip to content
Draft
23 changes: 9 additions & 14 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,20 @@ jobs:
name: test if ecs-tool can be built
runs-on: ubuntu-latest
steps:
-
name: checkout
uses: actions/checkout@v2
-
name: set up Go
uses: actions/setup-go@v1
- name: checkout
uses: actions/checkout@v4
- name: set up Go
uses: actions/setup-go@v5
with:
go-version: 1.15.x
-
name: cache modules
uses: actions/cache@v2
go-version: 1.21.x
- name: cache modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
-
name: download dependencies
- name: download dependencies
run: go mod download
-
name: build the app
- name: build the app
run: go build
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ jobs:
steps:
-
name: checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0 # needed for tags
-
name: set up Go
uses: actions/setup-go@v1
uses: actions/setup-go@v5
with:
go-version: 1.17.x
go-version: 1.21.x
-
name: run GoReleaser
uses: goreleaser/goreleaser-action@v1
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,27 @@ So that `--cluster` can be set by `ECS_CLUSTER` environmental variable, or `--ta

Also, `ecs-tool` exit code is the same as the container exit code.

### runFargate

The runFargate function is a command that is integrated into the ecs-tool utility. This tool simplifies running commands on an AWS ECS (Elastic Container Service) cluster with Fargate.

That normany use subnet with 'private' 'Tier' tag but if there is zero proivate subnets that will use 'public'

```
ecs-tool runFargate -e "preview" -- env
```

### EXEC

ecs-tool exec Executes a specified command in a running container on an ECS Fargate cluster and get the output.
That function use existing container, so it's faster than runFargate
This command also could connect to fargate existing task:

```
ecs-tool exec -e "preview" /bin/sh
```


### SSH

'SSH' access availabe to developers using `ecs-tool ssh`
Expand Down
64 changes: 64 additions & 0 deletions cmd/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package cmd

import (
"os"
"strings"

"github.com/apex/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/springload/ecs-tool/lib"
)

var execCmd = &cobra.Command{
Use: "exec",
Short: "Executes a command in an existing ECS Fargate container",

Long: `Executes a specified command in a running container on an ECS Fargate cluster.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
viper.SetDefault("run.launch_type", "FARGATE")
var containerName string
var commandArgs []string
if name := viper.GetString("container_name"); name == "" {
// If container_name not provided via flag, use first arg as container name
if len(args) < 2 {
log.Error("When --container_name is not provided, at least 2 arguments are required: <container_name> <command>")
os.Exit(1)
}
containerName = args[0]
commandArgs = args[1:]
} else {
containerName = name
commandArgs = args
}

// Validate that we have a command to execute
if len(commandArgs) == 0 {
log.Error("No command provided to execute")
os.Exit(1)
}

// Join the commandArgs to form a single command string
commandString := strings.Join(commandArgs, " ")

err := lib.ExecFargate(lib.ExecConfig{
Profile: viper.GetString("profile"),
Cluster: viper.GetString("cluster"),
Command: commandString,
TaskID: viper.GetString("task_id"),
TaskDefinitionName: viper.GetString("task_definition"),
ContainerName: containerName,
})
if err != nil {
log.WithError(err).Error("Can't execute command in Fargate mode")
os.Exit(1)
}
},
}

func init() {
rootCmd.AddCommand(execCmd)
execCmd.PersistentFlags().StringP("task_id", "", "", "Task ID to use (will auto-extract task definition)")
viper.BindPFlag("task_id", execCmd.PersistentFlags().Lookup("task_id"))
}
5 changes: 5 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,17 @@ func init() {
rootCmd.PersistentFlags().StringP("workdir", "w", "", "Set working directory")
rootCmd.PersistentFlags().StringP("image_tag", "", "", "Overrides the docker image tag in all container definitions. Overrides \"--image-tags\" flag.")
rootCmd.PersistentFlags().StringSliceP("image_tags", "", []string{}, "Modifies the docker image tags in container definitions. Can be specified several times, one for each container definition. Also takes comma-separated values in one tag. I.e. if there are 2 containers and --image-tags is set once to \"new\", then the image tag of the first container will be modified, leaving the second one untouched. Gets overridden by \"--image-tag\". If you have 3 container definitions and want to modify tags for the 1st and the 3rd, but leave the 2nd unchanged, specify it as \"--image_tags first_tag,,last_tag\".")
rootCmd.PersistentFlags().StringP("task_definition", "t", "", "Name of the ECS task definition to use (required)")



viper.BindPFlag("profile", rootCmd.PersistentFlags().Lookup("profile"))
viper.BindPFlag("cluster", rootCmd.PersistentFlags().Lookup("cluster"))
viper.BindPFlag("workdir", rootCmd.PersistentFlags().Lookup("workdir"))
viper.BindPFlag("image_tag", rootCmd.PersistentFlags().Lookup("image_tag"))
viper.BindPFlag("image_tags", rootCmd.PersistentFlags().Lookup("image_tags"))
viper.BindPFlag("task_definition", rootCmd.PersistentFlags().Lookup("task_definition"))


}

Expand Down
5 changes: 2 additions & 3 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ It can modify the container command.
`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
viper.SetDefault("run.launch_type", "EC2")
var containerName string
var commandArgs []string
if name := viper.GetString("container_name"); name == "" {
Expand Down Expand Up @@ -52,9 +53,7 @@ func init() {
rootCmd.AddCommand(runCmd)
runCmd.PersistentFlags().StringP("log_group", "l", "", "Name of the log group to get output")
runCmd.PersistentFlags().StringP("container_name", "", "", "Name of the container to modify parameters for")
runCmd.PersistentFlags().StringP("task_definition", "t", "", "name of task definition to use (required)")
viper.BindPFlag("log_group", runCmd.PersistentFlags().Lookup("log_group"))
viper.BindPFlag("container_name", runCmd.PersistentFlags().Lookup("container_name"))
viper.BindPFlag("task_definition", runCmd.PersistentFlags().Lookup("task_definition"))
viper.SetDefault("run.launch_type", "EC2")
//viper.BindPFlag("task_definition", runCmd.PersistentFlags().Lookup("task_definition"))
}
55 changes: 55 additions & 0 deletions cmd/runFargate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
"os"

"github.com/apex/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/springload/ecs-tool/lib"
)

var runFargateCmd = &cobra.Command{
Use: "runFargate",
Short: "Runs a command in Fargate mode",
Long: `Runs the specified command on an ECS cluster, optionally catching its output.

This command is specifically tailored for future Fargate-specific functionality.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
viper.SetDefault("run.launch_type", "FARGATE")
viper.SetDefault("run.security_group_filter", "ec2")
var containerName string
var commandArgs []string
if name := viper.GetString("container_name"); name == "" {
containerName = args[0]
commandArgs = args[1:]
} else {
containerName = name
commandArgs = args
}

exitCode, err := lib.RunFargate(
viper.GetString("profile"),
viper.GetString("cluster"),
viper.GetString("run.service"),
viper.GetString("task_definition"),
viper.GetString("image_tag"),
viper.GetStringSlice("image_tags"),
viper.GetString("workdir"),
containerName,
viper.GetString("log_group"),
viper.GetString("run.launch_type"),
viper.GetString("run.security_group_filter"),
commandArgs,
)
if err != nil {
log.WithError(err).Error("Can't run task in Fargate mode")
}
os.Exit(exitCode)
},
}

func init() {
rootCmd.AddCommand(runFargateCmd)
}
49 changes: 41 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,36 +1,69 @@
module github.com/springload/ecs-tool

go 1.17
go 1.21

require (
github.com/Shopify/ejson v1.2.1
github.com/apex/log v1.0.0
github.com/aws/aws-sdk-go v1.55.5
github.com/aws/aws-sdk-go v1.43.24
github.com/aws/aws-sdk-go-v2 v1.26.1
github.com/aws/aws-sdk-go-v2/config v1.26.3
github.com/aws/aws-sdk-go-v2/service/ecs v1.41.7
github.com/fujiwara/ecsta v0.4.5
github.com/imdario/mergo v0.3.11
github.com/spf13/cobra v0.0.3
github.com/spf13/viper v1.0.2
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
golang.org/x/crypto v0.14.0
)

require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/Songmu/flextime v0.1.0 // indirect
github.com/Songmu/prompter v0.5.1 // indirect
github.com/alecthomas/kong v0.7.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.31.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
github.com/aws/aws-sdk-go-v2/service/sns v1.26.7 // indirect
github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
github.com/aws/smithy-go v1.20.2 // indirect
github.com/creack/pty v1.1.20 // indirect
github.com/dustin/gojson v0.0.0-20160307161227-2e71ec9dd5ad // indirect
github.com/fsnotify/fsnotify v1.4.7 // indirect
github.com/fujiwara/tracer v1.0.2 // indirect
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/itchyny/gojq v0.12.11 // indirect
github.com/itchyny/timefmt-go v0.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/magiconair/properties v1.8.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.3.4 // indirect
github.com/samber/lo v1.36.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/spf13/afero v1.1.1 // indirect
github.com/spf13/cast v1.2.0 // indirect
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect
github.com/spf13/pflag v1.0.1 // indirect
github.com/stretchr/testify v1.5.1 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
github.com/tkuchiki/go-timezone v0.2.2 // indirect
github.com/tkuchiki/parsetime v0.3.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
Loading
Loading