Skip to content

Commit

Permalink
Exit with 1 if watch ends in an error state
Browse files Browse the repository at this point in the history
  • Loading branch information
lox committed Feb 24, 2018
1 parent 7626bab commit 03d3f2e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
9 changes: 8 additions & 1 deletion cmd/watch-stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package cmd

import (
"fmt"
"os"

"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/fatih/color"
"github.com/lox/parfait/stacks"
"gopkg.in/alecthomas/kingpin.v2"
)
Expand All @@ -20,8 +22,13 @@ func ConfigureWatchStack(app *kingpin.Application, sess client.ConfigProvider) {
StringVar(&stackName)

cmd.Action(func(c *kingpin.ParseContext) error {
return stacks.Watch(cloudformation.New(sess), stackName, func(event *cloudformation.StackEvent) {
err := stacks.Watch(cloudformation.New(sess), stackName, func(event *cloudformation.StackEvent) {
fmt.Printf("%s\n", stacks.FormatStackEvent(event))
})
if err != nil {
fmt.Printf("\n%v\n\n", color.RedString(err.Error()))
os.Exit(1)
}
return nil
})
}
38 changes: 30 additions & 8 deletions stacks/cloudformation.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,24 +205,46 @@ func Outputs(svc cfnInterface, name string) (map[string]string, error) {
return outputs, nil
}

func IsFailed(svc cfnInterface, name string) (bool, error) {
func Status(svc cfnInterface, name string) (string, error) {
resp, err := svc.DescribeStacks(&cloudformation.DescribeStacksInput{
StackName: aws.String(name),
})
if err != nil {
return true, err
return "", err
}

if len(resp.Stacks) != 1 {
return true, fmt.Errorf("Expected 1 stack, got %d", len(resp.Stacks))
return "", fmt.Errorf("Expected 1 stack, got %d", len(resp.Stacks))
}

log.Printf("%#v", *resp.Stacks[0].StackStatus)
return *resp.Stacks[0].StackStatus, nil
}

outputs := map[string]string{}
for _, output := range resp.Stacks[0].Outputs {
outputs[*output.OutputKey] = *output.OutputValue
func GetError(svc cfnInterface, name string) error {
status, err := Status(svc, name)
if err != nil {
return err
}

switch status {
case cloudformation.ResourceStatusUpdateFailed:
return fmt.Errorf("Stack failed to update")

case cloudformation.ResourceStatusCreateFailed:
return fmt.Errorf("Stack failed to create")

case cloudformation.StackStatusRollbackComplete:
return fmt.Errorf("Stack rollback succeeded")

case cloudformation.StackStatusRollbackFailed:
return fmt.Errorf("Stack rollback failed")

case cloudformation.StackStatusUpdateRollbackComplete:
return fmt.Errorf("Stack update failed, rollback succeeded")

case cloudformation.StackStatusUpdateRollbackFailed:
return fmt.Errorf("Stack update failed, rollback failed")
}

return false, nil
return nil
}
5 changes: 2 additions & 3 deletions stacks/watch.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package stacks

import (
"errors"
"fmt"

"github.com/aws/aws-sdk-go/service/cloudformation"
Expand All @@ -14,8 +13,8 @@ func Watch(cfn cfnInterface, stackName string, f func(event *cloudformation.Stac
return err
}

if failed, _ := IsFailed(cfn, stackName); failed {
return errors.New("Stack has failed")
if err = GetError(cfn, stackName); err != nil {
return err
}

outputs, err := Outputs(cfn, stackName)
Expand Down

0 comments on commit 03d3f2e

Please sign in to comment.