Skip to content

Commit 117ab1b

Browse files
committed
start working on exec
1 parent c2c4b14 commit 117ab1b

File tree

6 files changed

+130
-107
lines changed

6 files changed

+130
-107
lines changed

cmd/exec.go

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,68 +2,49 @@ package cmd
22

33
import (
44
"os"
5+
56
"github.com/apex/log"
67
"github.com/spf13/cobra"
78
"github.com/spf13/viper"
8-
"github.com/aws/aws-sdk-go/aws"
9-
"github.com/aws/aws-sdk-go/aws/session"
10-
"github.com/aws/aws-sdk-go/service/ecs"
119
"github.com/springload/ecs-tool/lib"
1210
)
1311

14-
// execCmd executes a command in an existing ECS Fargate container.
1512
var execCmd = &cobra.Command{
1613
Use: "exec",
1714
Short: "Executes a command in an existing ECS Fargate container",
18-
Long: `Executes a specified command in a running container on an ECS Fargate cluster.
19-
This command allows for interactive sessions and command execution in Fargate.`,
15+
16+
Long: `Executes a specified command in a running container on an ECS Fargate cluster.`,
2017
Args: cobra.MinimumNArgs(1),
2118
Run: func(cmd *cobra.Command, args []string) {
22-
// Command to be executed within the container
23-
command := args[0]
24-
25-
// Establish an AWS session using the specified profile and region from configuration
26-
sess, err := session.NewSessionWithOptions(session.Options{
27-
Profile: viper.GetString("profile"),
28-
Config: aws.Config{
29-
Region: aws.String(viper.GetString("region")),
30-
},
31-
})
32-
if err != nil {
33-
log.WithError(err).Error("Failed to create AWS session")
34-
os.Exit(1)
19+
viper.SetDefault("run.launch_type", "FARGATE")
20+
var containerName string
21+
var commandArgs []string
22+
if name := viper.GetString("container_name"); name == "" {
23+
containerName = args[0]
24+
commandArgs = args[1:]
25+
} else {
26+
containerName = name
27+
commandArgs = args
3528
}
3629

37-
// Create a new ECS service client with the session
38-
svc := ecs.New(sess)
39-
40-
// Execute the command in the specified ECS container using the ECS service client
41-
err = lib.ExecuteCommandInContainer(svc, viper.GetString("cluster"), viper.GetString("service_name"), viper.GetString("container_name"), command)
30+
exitCode, err := lib.ExecFargate(
31+
viper.GetString("profile"),
32+
viper.GetString("cluster"),
33+
viper.GetString("run.service"),
34+
viper.GetString("workdir"),
35+
containerName,
36+
viper.GetString("log_group"),
37+
viper.GetString("run.launch_type"),
38+
viper.GetString("run.security_group_filter"),
39+
commandArgs,
40+
)
4241
if err != nil {
43-
log.WithError(err).Error("Failed to execute command in ECS Fargate container")
44-
os.Exit(1)
45-
} else {
46-
log.Info("Command executed successfully in ECS Fargate container")
47-
os.Exit(0)
42+
log.WithError(err).Error("Can't run task in Fargate mode")
4843
}
44+
os.Exit(exitCode)
4945
},
5046
}
5147

5248
func init() {
5349
rootCmd.AddCommand(execCmd)
54-
execCmd.Flags().String("profile", "", "AWS profile to use")
55-
execCmd.Flags().String("region", "", "AWS region to operate in")
56-
execCmd.Flags().String("cluster", "", "Name of the ECS cluster")
57-
execCmd.Flags().String("service_name", "", "Name of the ECS service")
58-
execCmd.Flags().String("container_name", "", "Name of the container in the task")
59-
60-
viper.BindPFlag("profile", execCmd.Flags().Lookup("profile"))
61-
viper.BindPFlag("region", execCmd.Flags().Lookup("region"))
62-
viper.BindPFlag("cluster", execCmd.Flags().Lookup("cluster"))
63-
viper.BindPFlag("service_name", execCmd.Flags().Lookup("service_name"))
64-
viper.BindPFlag("container_name", execCmd.Flags().Lookup("container_name"))
65-
66-
// Set default values or read from a configuration file
67-
viper.SetDefault("region", "us-east-1")
68-
viper.SetDefault("container_name", "default-container")
6950
}

cmd/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ It can modify the container command.
1919
`,
2020
Args: cobra.MinimumNArgs(1),
2121
Run: func(cmd *cobra.Command, args []string) {
22+
viper.SetDefault("run.launch_type", "EC2")
2223
var containerName string
2324
var commandArgs []string
2425
if name := viper.GetString("container_name"); name == "" {
@@ -56,6 +57,5 @@ func init() {
5657
viper.BindPFlag("log_group", runCmd.PersistentFlags().Lookup("log_group"))
5758
viper.BindPFlag("container_name", runCmd.PersistentFlags().Lookup("container_name"))
5859
//viper.BindPFlag("task_definition", runCmd.PersistentFlags().Lookup("task_definition"))
59-
viper.SetDefault("run.launch_type", "EC2")
6060
fmt.Println("Default launch_type set to:", viper.GetString("run.launch_type"))
6161
}

cmd/runFargate.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ var runFargateCmd = &cobra.Command{
1717
This command is specifically tailored for future Fargate-specific functionality but currently duplicates the 'run' command.`,
1818
Args: cobra.MinimumNArgs(1),
1919
Run: func(cmd *cobra.Command, args []string) {
20+
viper.SetDefault("run.launch_type", "FARGATE")
21+
viper.SetDefault("run.security_group_filter", "ec2")
2022
var containerName string
2123
var commandArgs []string
2224
if name := viper.GetString("container_name"); name == "" {
@@ -50,8 +52,4 @@ This command is specifically tailored for future Fargate-specific functionality
5052

5153
func init() {
5254
rootCmd.AddCommand(runFargateCmd)
53-
viper.SetDefault("run.security_group_filter", "*ec2*")
54-
viper.SetDefault("run.launch_type", "FARGATE")
55-
56-
5755
}

lib/exec.go

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,33 @@ package lib
22

33
import (
44
"fmt"
5+
"github.com/apex/log"
56
"github.com/aws/aws-sdk-go/aws"
6-
//"github.com/aws/aws-sdk-go/aws/session"
7+
"github.com/aws/aws-sdk-go/aws/session"
78
"github.com/aws/aws-sdk-go/service/ecs"
89
"github.com/aws/aws-sdk-go/service/ecs/ecsiface"
910
)
1011

11-
// FindLatestTaskArn finds the latest task ARN for the specified service within a cluster
12-
func FindLatestTaskArn(svc ecsiface.ECSAPI, clusterName, serviceName string) (string, error) {
12+
// InitializeSession creates an AWS session for ECS interaction
13+
func InitializeSession(region, profile string) (*session.Session, error) {
14+
sess, err := session.NewSessionWithOptions(session.Options{
15+
Profile: profile,
16+
Config: aws.Config{
17+
},
18+
})
19+
if err != nil {
20+
log.WithError(err).Error("Failed to create AWS session")
21+
return nil, err
22+
}
23+
return sess, nil
24+
}
25+
26+
// FindLatestTaskArn locates the most recent task ARN for a specified ECS service
27+
func FindLatestTaskArn(clusterName, serviceName string) (string, error) {
28+
if serviceName == "" {
29+
return "", fmt.Errorf("service name cannot be empty")
30+
}
31+
1332
input := &ecs.ListTasksInput{
1433
Cluster: aws.String(clusterName),
1534
ServiceName: aws.String(serviceName),
@@ -18,20 +37,35 @@ func FindLatestTaskArn(svc ecsiface.ECSAPI, clusterName, serviceName string) (st
1837
}
1938

2039
result, err := svc.ListTasks(input)
21-
if err != nil || len(result.TaskArns) == 0 {
40+
if err != nil {
41+
log.WithError(err).Error("Error listing tasks")
42+
return "", fmt.Errorf("error listing tasks for service %s on cluster %s: %v", serviceName, clusterName, err)
43+
}
44+
if len(result.TaskArns) == 0 {
45+
log.WithFields(log.Fields{
46+
"cluster": clusterName,
47+
"service": serviceName,
48+
}).Error("No running tasks found")
2249
return "", fmt.Errorf("no running tasks found for service %s on cluster %s", serviceName, clusterName)
2350
}
2451

52+
log.WithFields(log.Fields{
53+
"taskArn": aws.StringValue(result.TaskArns[0]),
54+
}).Info("Found latest task ARN")
2555
return aws.StringValue(result.TaskArns[0]), nil
2656
}
2757

28-
// ExecuteCommandInContainer executes a specified command in a running container on an ECS Fargate cluster.
29-
func ExecuteCommandInContainer(svc ecsiface.ECSAPI, cluster, serviceName, containerName, command string) error {
30-
taskArn, err := FindLatestTaskArn(svc, cluster, serviceName)
58+
// ExecuteCommandInContainer runs a command in a specified container on an ECS Fargate service
59+
func ExecFargate(rofile, cluster, service, container, workDir, containerName, awslogGroup, launchType string, command string) (exitCode int, err error) {
60+
if service == "" {
61+
return fmt.Errorf("service name cannot be empty")
62+
}
63+
64+
taskArn, err := FindLatestTaskArn(cluster, serviceName)
3165
if err != nil {
3266
return err
3367
}
34-
68+
fmt.Println(taskArn , "we are here")
3569
input := &ecs.ExecuteCommandInput{
3670
Cluster: aws.String(cluster),
3771
Task: aws.String(taskArn),
@@ -42,8 +76,18 @@ func ExecuteCommandInContainer(svc ecsiface.ECSAPI, cluster, serviceName, contai
4276

4377
_, err = svc.ExecuteCommand(input)
4478
if err != nil {
79+
log.WithError(err).WithFields(log.Fields{
80+
"taskArn": taskArn,
81+
"containerName": containerName,
82+
"command": command,
83+
}).Error("Failed to execute command")
4584
return fmt.Errorf("failed to execute command: %v", err)
4685
}
4786

87+
log.WithFields(log.Fields{
88+
"taskArn": taskArn,
89+
"containerName": containerName,
90+
"command": command,
91+
}).Info("Command executed successfully")
4892
return nil
4993
}

lib/runFargate.go

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func RunFargate(profile, cluster, service, taskDefinitionName, imageTag string,
1717
}
1818
ctx := log.WithFields(log.Fields{"task_definition": taskDefinitionName})
1919

20+
2021
svc := ecs.New(localSession)
2122
svcEC2 := ec2.New(localSession) // Assuming makeSession initializes localSession
2223

@@ -26,13 +27,11 @@ func RunFargate(profile, cluster, service, taskDefinitionName, imageTag string,
2627
log.WithError(err).Error("Failed to fetch subnets by tag")
2728
return 1, err
2829
}
29-
3030
securityGroups, err := fetchSecurityGroupsByName(svcEC2, securityGroupFilter)
31-
if err != nil {
31+
if err != nil {
3232
log.WithError(err).Error("Failed to fetch security groups by name")
3333
return 1, err
3434
}
35-
3635
// Set up network configuration
3736
networkConfiguration := &ecs.NetworkConfiguration{
3837
AwsvpcConfiguration: &ecs.AwsVpcConfiguration{
@@ -213,50 +212,3 @@ for _, task := range tasksOutput.Tasks {
213212

214213

215214

216-
// fetchSubnetsByTag fetches subnet IDs by a specific tag name and value
217-
func fetchSubnetsByTag(svc *ec2.EC2, tagKey, tagValue string) ([]*string, error) {
218-
input := &ec2.DescribeSubnetsInput{
219-
Filters: []*ec2.Filter{
220-
{
221-
Name: aws.String(fmt.Sprintf("tag:%s", tagKey)),
222-
Values: []*string{aws.String(tagValue)},
223-
},
224-
},
225-
}
226-
227-
result, err := svc.DescribeSubnets(input)
228-
if err != nil {
229-
return nil, fmt.Errorf("error describing subnets: %w", err)
230-
}
231-
232-
var subnets []*string
233-
for _, subnet := range result.Subnets {
234-
subnets = append(subnets, subnet.SubnetId)
235-
}
236-
237-
return subnets, nil
238-
}
239-
240-
241-
func fetchSecurityGroupsByName(svc *ec2.EC2, securityGroupFilter string) ([]*string, error) {
242-
input := &ec2.DescribeSecurityGroupsInput{
243-
Filters: []*ec2.Filter{
244-
{
245-
Name: aws.String("group-name"),
246-
Values: []*string{aws.String(securityGroupFilter)},
247-
},
248-
},
249-
}
250-
251-
result, err := svc.DescribeSecurityGroups(input)
252-
if err != nil {
253-
return nil, fmt.Errorf("error describing security groups: %w", err)
254-
}
255-
256-
var securityGroups []*string
257-
for _, sg := range result.SecurityGroups {
258-
securityGroups = append(securityGroups, sg.GroupId)
259-
}
260-
261-
return securityGroups, nil
262-
}

lib/util.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/aws/aws-sdk-go/aws/session"
1111
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
1212
"github.com/aws/aws-sdk-go/service/ecs"
13+
"github.com/aws/aws-sdk-go/service/ec2"
1314
)
1415

1516
var localSession *session.Session
@@ -133,3 +134,50 @@ func modifyContainerDefinitionImages(imageTag string, imageTags []string, workDi
133134
}
134135
return nil
135136
}
137+
138+
// fetchSubnetsByTag fetches subnet IDs by a specific tag name and value
139+
func fetchSubnetsByTag(svc *ec2.EC2, tagKey, tagValue string) ([]*string, error) {
140+
input := &ec2.DescribeSubnetsInput{
141+
Filters: []*ec2.Filter{
142+
{
143+
Name: aws.String(fmt.Sprintf("tag:%s", tagKey)),
144+
Values: []*string{aws.String(tagValue)},
145+
},
146+
},
147+
}
148+
149+
result, err := svc.DescribeSubnets(input)
150+
if err != nil {
151+
return nil, fmt.Errorf("error describing subnets: %w", err)
152+
}
153+
154+
var subnets []*string
155+
for _, subnet := range result.Subnets {
156+
subnets = append(subnets, subnet.SubnetId)
157+
}
158+
159+
return subnets, nil
160+
}
161+
162+
163+
func fetchSecurityGroupsByName(svc *ec2.EC2, securityGroupFilter string) ([]*string, error) {
164+
// Describe all security groups
165+
input := &ec2.DescribeSecurityGroupsInput{}
166+
167+
result, err := svc.DescribeSecurityGroups(input)
168+
if err != nil {
169+
return nil, fmt.Errorf("error describing security groups: %w", err)
170+
}
171+
172+
var securityGroups []*string
173+
// Loop through the security groups and add those that contain the filter in their name
174+
for _, sg := range result.SecurityGroups {
175+
if strings.Contains(*sg.GroupName, securityGroupFilter) {
176+
securityGroups = append(securityGroups, sg.GroupId)
177+
}
178+
}
179+
180+
// Return the filtered list of security group IDs
181+
return securityGroups, nil
182+
}
183+

0 commit comments

Comments
 (0)