Skip to content
This repository has been archived by the owner on Jan 14, 2020. It is now read-only.

Commit

Permalink
updated logging output
Browse files Browse the repository at this point in the history
  • Loading branch information
ojkelly committed Jul 4, 2018
1 parent 4538f8a commit 1e6e694
Show file tree
Hide file tree
Showing 14 changed files with 242 additions and 139 deletions.
2 changes: 1 addition & 1 deletion Gopkg.lock

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

16 changes: 0 additions & 16 deletions internal/cloudformation/example_test.go

This file was deleted.

17 changes: 0 additions & 17 deletions internal/cloudformation/tasks/auth.go
Expand Up @@ -95,23 +95,6 @@ func mfaTokenProvider() (string, error) {
// Ensure a session is returned, else fatal with an error explaning why no session was found
func must(sess *session.Session, err error) *session.Session {

// if err != nil {
// if awsErr, ok := err.(awserr.Error); ok {
// // Get error details
// log.Println("Error:", awsErr.Code(), awsErr.Message())

// // Prints out full error message, including original error if there was one.
// log.Println("Error:", awsErr.Error())

// // Get original error
// if origErr := awsErr.OrigErr(); origErr != nil {
// // operate on original error.
// }
// } else {
// fmt.Println(err.Error())
// }
// }

if err != nil {
if strings.Contains(err.Error(), "NoCredentialProviders") {
printer.Fatal(
Expand Down
22 changes: 19 additions & 3 deletions internal/cloudformation/tasks/delete.go
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"time"
printer "github.com/KablamoOSS/go-cli-printer"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudformation"
Expand All @@ -12,6 +13,7 @@ import (
// DeleteStack removes a cloudformation stack
func DeleteStack(stackName, profile, region string) {
cf := GetCloudformationClient(profile, region)
printer.Step(fmt.Sprintf("Delete Stack %s:", stackName))

//See if the stack exists to begin with
_, err := cf.DescribeStacks(&cloudformation.DescribeStacksInput{StackName: aws.String(stackName)})
Expand All @@ -21,13 +23,22 @@ func DeleteStack(stackName, profile, region string) {
checkError(err)

// status polling
PrintStackEventHeader()

for {
printer.Progress("Deleting")
time.Sleep(2 * time.Second)
status, _ := cf.DescribeStacks(&cloudformation.DescribeStacksInput{StackName: aws.String(stackName)})
status, err := cf.DescribeStacks(&cloudformation.DescribeStacksInput{StackName: aws.String(stackName)})
checkErrorDeletePoll(err)

events, _ := cf.DescribeStackEvents(&cloudformation.DescribeStackEventsInput{StackName: aws.String(stackName)})

if len(status.Stacks) > 0 {
stackStatus := *status.Stacks[0].StackStatus
fmt.Println(stackStatus)

if len(events.StackEvents) > 0 {
PrintStackEvent(events.StackEvents[0], false)
}
if stackStatus == cloudformation.StackStatusDeleteInProgress {
continue
}
Expand All @@ -40,7 +51,12 @@ func DeleteStack(stackName, profile, region string) {
if err != nil {
checkErrorDeletePoll(err)
} else {
fmt.Println("Delete successful")
printer.SubStep(
fmt.Sprintf("Success Delete Stack %s", stackName),
1,
true,
true,
)
os.Exit(0)
}
}
105 changes: 62 additions & 43 deletions internal/cloudformation/tasks/events.go
Expand Up @@ -5,63 +5,82 @@ import (

printer "github.com/KablamoOSS/go-cli-printer"
awsCF "github.com/aws/aws-sdk-go/service/cloudformation"

"github.com/ttacon/chalk"
"github.com/aws/aws-sdk-go/aws"
)

var lineFormat = "%-19v | %-35v | %-40v | %-50v | %-30v "

// PrintStackEvents outputs the events of a stack
// TODO: add flags to allow printing all events, and default only to recent events
func PrintStackEvents(cf *awsCF.CloudFormation, stackName string) {
status, err := cf.DescribeStackEvents(&awsCF.DescribeStackEventsInput{StackName: aws.String(stackName)})
checkError(err)

printer.Step(fmt.Sprintf("Events for %s:", stackName))

PrintStackEventHeader()

for i, event := range status.StackEvents {
var isLast bool
if i + 1 == len(status.StackEvents) {
isLast = true
}
PrintStackEvent(event, isLast)
}
}

// PrintStackEventHeader prints the header
func PrintStackEventHeader(){
printer.SubStep(
fmt.Sprintf(" %-19v | %-22v | %-30v | %v | %v | \n", "Time", "Status", "Type", "LogicalID", "Status Reason"),
fmt.Sprintf(
chalk.Bold.TextStyle(lineFormat),
"Time",
"Status",
"Type",
"LogicalID",
"Status Reason",
),
1,
false,
true,
)
for _, event := range status.StackEvents {
if event.Timestamp != nil {
printer.SubStep(
fmt.Sprintf(" %-19v |", event.Timestamp.Format("2006-01-2 15:04:05")),
1,
false,
true,
)
}
if event.ResourceStatus != nil {
printer.SubStep(
fmt.Sprintf(" %-22v |", *event.ResourceStatus),
1,
false,
true,
)
}
if event.ResourceType != nil {
printer.SubStep(
fmt.Sprintf(" %-30v |", *event.ResourceType),
1,
false,
true,
)
}
if event.LogicalResourceId != nil {
printer.SubStep(
fmt.Sprintf(" %v |", *event.LogicalResourceId),
1,
false,
true,
)
}
if event.ResourceStatusReason != nil {
printer.SubStep(
fmt.Sprintf(" %v |", *event.ResourceStatusReason),
1,
false,
true,
)
}
}

// PrintStackEvent prints a single event
func PrintStackEvent(event *awsCF.StackEvent, isLast bool) {
var timeStamp,
resourceStatus,
resourceType,
logicalResourceID,
resourceStatusReason string
if event.Timestamp != nil {
timeStamp = event.Timestamp.Format("2006-01-02 15:04:05")
}
if event.ResourceStatus != nil {
resourceStatus= *event.ResourceStatus
}
if event.ResourceType != nil {
resourceType = *event.ResourceType
}
if event.LogicalResourceId != nil {
logicalResourceID = *event.LogicalResourceId
}
if event.ResourceStatusReason != nil {
resourceStatusReason = *event.ResourceStatusReason
}

printer.SubStep(
fmt.Sprintf(
lineFormat,
timeStamp,
resourceStatus,
resourceType,
logicalResourceID,
resourceStatusReason,
),
1,
isLast,
true,
)
}
76 changes: 45 additions & 31 deletions internal/cloudformation/tasks/upsert.go
Expand Up @@ -21,18 +21,22 @@ func UpsertStack(
) {

var err error
var status *awsCF.DescribeStacksOutput
var action string

// use template from file
_, err = cf.DescribeStacks(&awsCF.DescribeStacksInput{StackName: aws.String(stackName)})
if err == nil { //update
action = "Updating"
printer.Step(fmt.Sprintf("%s Stack %s:", action, stackName))
_, err = cf.UpdateStack(&awsCF.UpdateStackInput{
StackName: aws.String(stackName),
TemplateBody: aws.String(string(templateBody)),
Parameters: parameters,
Capabilities: capabilities,
})
} else {
action = "Creating"
printer.Step(fmt.Sprintf("%s Stack %s:", action, stackName))
_, err = cf.CreateStack(&awsCF.CreateStackInput{
StackName: aws.String(stackName),
TemplateBody: aws.String(string(templateBody)),
Expand All @@ -42,31 +46,7 @@ func UpsertStack(
}
checkError(err)

// Make sure upsert works
for {
time.Sleep(2 * time.Second)
status, err = cf.DescribeStacks(&awsCF.DescribeStacksInput{StackName: aws.String(stackName)})
checkError(err)
if len(status.Stacks) > 0 {
stack := status.Stacks[0]
stackStatus := *stack.StackStatus
fmt.Println(stackStatus)
if stackStatus != awsCF.StackStatusCreateInProgress &&
stackStatus != awsCF.StackStatusUpdateInProgress &&
stackStatus != awsCF.StackStatusUpdateCompleteCleanupInProgress {
if stackStatus == awsCF.StackStatusCreateComplete ||
stackStatus == awsCF.StackStatusUpdateComplete {
os.Exit(0)
} else {
printer.Error(fmt.Errorf("Upsert Failed"), "", "")
time.Sleep(2 * time.Second)

PrintStackEvents(cf, stackName)
os.Exit(1)
}
}
}
}
processUpsert(stackName, action, cf)
}

// UpsertStackViaS3 -
Expand All @@ -79,18 +59,23 @@ func UpsertStackViaS3(
) {

var err error
var status *awsCF.DescribeStacksOutput
var action string

// use cf template url
_, err = cf.DescribeStacks(&awsCF.DescribeStacksInput{StackName: aws.String(stackName)})
if err == nil { //update
action = "Updating"
printer.Step(fmt.Sprintf("%s Stack %s:", action, stackName))

_, err = cf.UpdateStack(&awsCF.UpdateStackInput{
StackName: aws.String(stackName),
TemplateURL: aws.String(templateURL),
Parameters: parameters,
Capabilities: capabilities,
})
} else { //create
action = "Creating"
printer.Step(fmt.Sprintf("%s Stack %s:", action, stackName))
_, err = cf.CreateStack(&awsCF.CreateStackInput{
StackName: aws.String(stackName),
TemplateURL: aws.String(templateURL),
Expand All @@ -100,26 +85,55 @@ func UpsertStackViaS3(
}
checkError(err)

// Make sure upsert works
processUpsert(stackName, action, cf)

}

func processUpsert(stackName, action string, cf *awsCF.CloudFormation ){
var err error
var status *awsCF.DescribeStacksOutput

PrintStackEventHeader()
for {
printer.Progress(action)
time.Sleep(2 * time.Second)
status, err = cf.DescribeStacks(&awsCF.DescribeStacksInput{StackName: aws.String(stackName)})
checkError(err)

events, err := cf.DescribeStackEvents(&awsCF.DescribeStackEventsInput{StackName: aws.String(stackName)})
checkError(err)

if len(status.Stacks) > 0 {

stack := status.Stacks[0]
stackStatus := *stack.StackStatus
fmt.Println(stackStatus)

if len(events.StackEvents) > 0 {
PrintStackEvent(events.StackEvents[0], false)
}

if stackStatus != awsCF.StackStatusCreateInProgress &&
stackStatus != awsCF.StackStatusUpdateInProgress &&
stackStatus != awsCF.StackStatusUpdateCompleteCleanupInProgress {
if stackStatus == awsCF.StackStatusCreateComplete ||
stackStatus == awsCF.StackStatusUpdateComplete {
printer.SubStep(
fmt.Sprintf("Success %s Stack %s", action, stackName),
1,
true,
true,
)
os.Exit(0)
} else {
printer.SubStep(
fmt.Sprintf("Fail %s Stack %s", action, stackName),
1,
true,
true,
)

printer.Error(fmt.Errorf("Upsert Failed"), "", "")
time.Sleep(2 * time.Second)

PrintStackEvents(cf, stackName)
os.Exit(1)
}
}
Expand Down
6 changes: 6 additions & 0 deletions internal/cloudformation/tasks/util.go
Expand Up @@ -28,6 +28,12 @@ func checkErrorDeletePoll(err error) {
printer.Fatal(fmt.Errorf("No updates are to be performed"), "", "")
os.Exit(0)
} else if strings.Contains(err.Error(), "Stack with id") && strings.Contains(err.Error(), "does not exist") {
printer.SubStep(
fmt.Sprintf("Success: Deleted Stack"),
1,
true,
true,
)
os.Exit(0)
} else {
printer.Fatal(err, "", "")
Expand Down

0 comments on commit 1e6e694

Please sign in to comment.