Skip to content

Commit

Permalink
Fixed #95
Browse files Browse the repository at this point in the history
  • Loading branch information
null93 committed Jun 15, 2022
1 parent 35edb0b commit 3e797dc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 63 deletions.
7 changes: 1 addition & 6 deletions cmd/jrctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@ package main

import (
"github.com/jetrails/jrctl/internal"
"github.com/jetrails/jrctl/pkg/env"
)

func main() {
internal.RootCmd.Execute()
}

func init() {
env.EnvPrefix = "JR_"
}
}
109 changes: 68 additions & 41 deletions internal/aws-autoscale-detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package internal

import (
"context"
"errors"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
Expand All @@ -15,6 +16,12 @@ import (
"github.com/spf13/cobra"
)

var (
ErrAwsImdsCredsMissing = errors.New("failed to extract credentials from IMDS service")
ErrAwsAutoScalingGroupNotFound = errors.New("failed to find autoscaling group with that name")
ErrAwsInstanceDetails = errors.New("failed to query instance details")
)

func GetAWSConfig() (aws.Config, error) {
return config.LoadDefaultConfig(
context.TODO(),
Expand All @@ -34,6 +41,47 @@ func GetInstanceIdentityDocument(cfg aws.Config) *imds.InstanceIdentityDocument
return nil
}

func GetAutoScalingGroupInstances(cfg aws.Config, asgName string) ([]types.Instance, error) {
entries := []types.Instance{}
autoscalingClient := autoscaling.NewFromConfig(cfg)
ec2Client := ec2.NewFromConfig(cfg)

asgs, err := autoscalingClient.DescribeAutoScalingGroups(
context.TODO(),
&autoscaling.DescribeAutoScalingGroupsInput{AutoScalingGroupNames: []string{asgName}},
)

if err != nil {
return entries, ErrAwsAutoScalingGroupNotFound
}

for _, asg := range asgs.AutoScalingGroups {
instanceIds := []string{}
for _, instance := range asg.Instances {
instanceIds = append(instanceIds, aws.ToString(instance.InstanceId))
}
infos, err := ec2Client.DescribeInstances(context.TODO(), &ec2.DescribeInstancesInput{
InstanceIds: instanceIds,
Filters: []types.Filter{
{
Name: aws.String("instance-state-name"),
Values: []string{"running"},
},
},
})
if err != nil {
return []types.Instance{}, ErrAwsInstanceDetails
}
for _, reservation := range infos.Reservations {
for _, instance := range reservation.Instances {
entries = append(entries, instance)
}
}
}

return entries, nil
}

var awsAutoscaleDetectCmd = &cobra.Command{
Use: "autoscale-detect AUTOSCALING_GROUP_NAME",
Short: "Query aws for instances in autoscaling group",
Expand Down Expand Up @@ -64,51 +112,30 @@ var awsAutoscaleDetectCmd = &cobra.Command{

cfg, err := GetAWSConfig()
if err != nil {
output.ExitWithMessage(3, "\nfailed to extract credentials from IMDS service\n")
output.ExitWithMessage(3, "\n"+ErrAwsImdsCredsMissing.Error()+"\n")
}
autoscalingClient := autoscaling.NewFromConfig(cfg)
ec2Client := ec2.NewFromConfig(cfg)

asgs, err := autoscalingClient.DescribeAutoScalingGroups(
context.TODO(),
&autoscaling.DescribeAutoScalingGroupsInput{AutoScalingGroupNames: []string{asgName}},
)

if err != nil {
output.ExitWithMessage(3, "\nfailed to extract credentials from IMDS service\n")
}

for _, asg := range asgs.AutoScalingGroups {
instanceIds := []string{}
for _, instance := range asg.Instances {
instanceIds = append(instanceIds, aws.ToString(instance.InstanceId))
if instances, err := GetAutoScalingGroupInstances(cfg, asgName); err == nil {
for _, instance := range instances {
tbl.AddQuietEntry(aws.ToString(instance.PrivateIpAddress))
tbl.AddRow(Columns{
aws.ToString(instance.InstanceId),
aws.ToString(instance.ImageId),
"Running",
aws.ToString(instance.PrivateIpAddress),
aws.ToString(instance.PublicIpAddress),
instance.LaunchTime.String(),
})
}
infos, err := ec2Client.DescribeInstances(context.TODO(), &ec2.DescribeInstancesInput{
InstanceIds: instanceIds,
Filters: []types.Filter{
{
Name: aws.String("instance-state-name"),
Values: []string{"running"},
},
},
})
if err != nil {
output.ExitWithMessage(4, "\nfailed to query instance details\n")
}
for _, reservation := range infos.Reservations {
for _, instance := range reservation.Instances {
tbl.AddQuietEntry(aws.ToString(instance.PrivateIpAddress))
tbl.AddRow(Columns{
aws.ToString(instance.InstanceId),
aws.ToString(instance.ImageId),
"Running",
aws.ToString(instance.PrivateIpAddress),
aws.ToString(instance.PublicIpAddress),
instance.LaunchTime.String(),
})
}
} else {
switch err {
case ErrAwsAutoScalingGroupNotFound:
output.ExitWithMessage(4, "\n"+err.Error()+"\n")
case ErrAwsInstanceDetails:
output.ExitWithMessage(5, "\n"+err.Error()+"\n")
default:
output.ExitWithMessage(6, "\nunknown error\n")
}

}

output.Print()
Expand Down
54 changes: 38 additions & 16 deletions internal/aws-autoscale-ingest.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package internal

import (
"errors"
"fmt"
"strings"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/jetrails/jrctl/pkg/array"
"github.com/jetrails/jrctl/pkg/input"
. "github.com/jetrails/jrctl/pkg/output"
"github.com/jetrails/jrctl/pkg/text"
"github.com/jetrails/jrctl/sdk/config"
Expand All @@ -29,35 +28,58 @@ func NormalizeEndpoints(endpoints []string) []string {
}

var awsAutoscaleIngestCmd = &cobra.Command{
Use: "autoscale-ingest",
Short: "Display databases in deployment",
Example: text.Examples([]string{}),
Args: cobra.ExactArgs(0),
PreRunE: func(cmd *cobra.Command, args []string) error {
if !input.HasDataInPipe() {
return errors.New("must pipe endpoints to stdin")
}
return nil
},
Use: "autoscale-ingest AUTOSCALING_GROUP_NAME",
Short: "Display databases in deployment",
Example: text.Examples([]string{
"jrctl aws autoscale-ingest example-asg",
"jrctl aws autoscale-ingest example-asg -t www",
"jrctl aws autoscale-ingest example-asg -q",
}),
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
quiet, _ := cmd.Flags().GetBool("quiet")
tag, _ := cmd.Flags().GetString("type")
endpoints := NormalizeEndpoints(strings.Fields(input.GetPipeData()))
tags := []string{tag}
asgName := args[0]

output := NewOutput(quiet, tags)
privateIps := []string{}

cfg, err := GetAWSConfig()
if err != nil {
output.ExitWithMessage(3, "\n"+ErrAwsImdsCredsMissing.Error()+"\n")
}
if instances, err := GetAutoScalingGroupInstances(cfg, asgName); err == nil {
for _, instance := range instances {
privateIps = append(privateIps, aws.ToString(instance.PrivateIpAddress))
}
} else {
switch err {
case ErrAwsAutoScalingGroupNotFound:
output.ExitWithMessage(4, "\n"+err.Error()+"\n")
case ErrAwsInstanceDetails:
output.ExitWithMessage(5, "\n"+err.Error()+"\n")
default:
output.ExitWithMessage(6, "\nunknown error\n")
}
}
endpoints := NormalizeEndpoints(privateIps)
if len(endpoints) < 1 {
output.ExitWithMessage(3, "\nmust pass at least one endpoint\n")
output.ExitWithMessage(7, "\nmust pass at least one endpoint\n")
}

contexts := config.GetContexts(tags)
servers := []config.Entry{}
viper.UnmarshalKey("servers", &servers)

if len(contexts) < 1 {
output.PrintTags()
output.ExitWithMessage(8, "\nno servers found with given type selector\n")
}

if !config.ContextsHaveSameToken(contexts) {
output.PrintTags()
output.ExitWithMessage(4, "\nfound differing tokens, autoscale requires same tokens\n")
output.ExitWithMessage(9, "\nfound differing tokens, autoscale requires same tokens\n")
}

tbl := output.CreateTable(Columns{
Expand Down Expand Up @@ -114,6 +136,6 @@ func init() {
OnlyRunOnAWS(awsAutoscaleIngestCmd)
awsCmd.AddCommand(awsAutoscaleIngestCmd)
awsAutoscaleIngestCmd.Flags().SortFlags = true
awsAutoscaleIngestCmd.Flags().BoolP("quiet", "q", false, "output only errors")
awsAutoscaleIngestCmd.Flags().BoolP("quiet", "q", false, "display no output")
awsAutoscaleIngestCmd.Flags().StringP("type", "t", "www", "filter servers using type selectors, only one selector allowed")
}

0 comments on commit 3e797dc

Please # to comment.