func (s *StacksWatch) Run() error { client := cloudformation.NewFromEnv() seen := map[string]struct{}{} for { rsp, e := client.DescribeStackEvents(&cloudformation.DescribeStackEventsParameters{StackName: s.Name}) if e != nil { fmt.Printf("ERROR: %s\n", e.Error()) } else { events := StackEventsList(rsp.DescribeStackEventsResult.StackEvents) sort.Sort(events) for _, e := range events { _, ok := seen[e.EventId] if !ok { ph := e.PhysicalResourceId fmt.Printf("%s %-24s %-32s %s\n", e.Timestamp.Format(time.RFC3339), maxLen(e.LogicalResourceId, 24), maxLen(ph, 32), e.ResourceStatus) switch e.ResourceStatusReason { case "", ReasonUserInitiated, ReasonResourceCreationInitiated: // default: fmt.Printf("%20s %s\n", "", gocli.Red(e.ResourceStatusReason)) } seen[e.EventId] = struct{}{} } } } time.Sleep(time.Duration(s.Refresh) * time.Second) } return nil }
func (a *ParametersDescribe) Run() error { client := cloudformation.NewFromEnv() tpl := cloudformation.DescribeStacks{ StackName: a.Name, } rsp, e := tpl.Execute(client) if e != nil { return e } stacks := rsp.DescribeStacksResult.Stacks if len(stacks) != 1 { return fmt.Errorf("expected 1 stack for %q, got %d", a.Name, len(stacks)) } stack := stacks[0] t := gocli.NewTable() for _, p := range stack.Parameters { value := p.ParameterValue if len(value) > 64 && !a.Full { value = value[0:64] + "... (truncated)" } t.Add(p.ParameterKey, value) } fmt.Println(t) return nil }
func resources(name string) { cf := cloudformation.NewFromEnv() ec2Client := ec2.NewFromEnv() elbClient := elb.NewFromEnv() resources, err := cf.DescribeStackResources( cloudformation.DescribeStackResourcesParameters{ StackName: name, }, ) if err != nil { fatal(err) } stub := make(map[string]map[string]interface{}) for _, resource := range resources.DescribeStackResourcesResult.StackResources { typeSegments := strings.Split(resource.ResourceType, "::") typeBase := typeSegments[len(typeSegments)-1] byType, found := stub[typeBase] if !found { byType = make(map[string]interface{}) stub[typeBase] = byType } cleanName := strings.Replace(resource.LogicalResourceId, typeBase, "", 1) if cleanName == "" { cleanName = resource.LogicalResourceId } byType[cleanName] = resource.PhysicalResourceId } err = grabSecurityGroupNames(stub, ec2Client) if err != nil { fatal(err) } err = grabSubnetInfo(stub, ec2Client) if err != nil { fatal(err) } err = grabLoadBalancerDNSNames(stub, elbClient) if err != nil { fatal(err) } err = candiedyaml.NewEncoder(os.Stdout).Encode(map[string]interface{}{ "Region": ec2Client.Client.Region, "AccessKeyID": ec2Client.Client.Key, "SecretAccessKey": ec2Client.Client.Secret, "Resources": stub, }) if err != nil { fatal(err) } }
func watch(name string) { deployer := deployer.New(cloudformation.NewFromEnv()) events := make(chan *cloudformation.StackEvent) go deployer.Watch(events, name) ok := streamEvents(events) if !ok { fmt.Println() fatal(ansi.Color("formation failed and was rolled back", "yellow")) } }
func (r *StackResources) Run() error { client := cloudformation.NewFromEnv() rsp, e := client.DescribeStackResources(cloudformation.DescribeStackResourcesParameters{ StackName: r.Name, }) if e != nil { return e } t := gocli.NewTable() for _, r := range rsp.DescribeStackResourcesResult.StackResources { t.Add(r.LogicalResourceId, r.PhysicalResourceId) } fmt.Println(t) return nil }
func deploy(name string, source io.Reader) { template, err := ioutil.ReadAll(source) if err != nil { fatal(err) } deployer := deployer.New(cloudformation.NewFromEnv()) events, err := deployer.Deploy(name, template) if err != nil { panic(err) } ok := streamEvents(events) if !ok { fmt.Println() fatal(ansi.Color("formation failed and was rolled back", "yellow")) } }
func (r *StackDescription) Run() error { client := cloudformation.NewFromEnv() rsp, e := client.DescribeStacks(&cloudformation.DescribeStacksParameters{ StackName: r.Name, }) if e != nil { return e } if rsp.DescribeStacksResult == nil || len(rsp.DescribeStacksResult.Stacks) == 0 { return nil } s := rsp.DescribeStacksResult.Stacks[0] t := gocli.NewTable() t.Add("name", s.StackName) t.Add("created", s.CreationTime) t.Add("state", s.StackStatus) if len(s.Parameters) > 0 { t := gocli.NewTable() fmt.Println("Parameters:") for _, p := range s.Parameters { t.Add(p.ParameterKey, p.ParameterValue) } fmt.Println(t) } else { fmt.Println("Parameters: none") } if len(s.Outputs) > 0 { t := gocli.NewTable() fmt.Println("Outputs:") for _, p := range s.Outputs { t.Add(p.OutputKey, p.OutputValue) } fmt.Println(t) } else { fmt.Println("Outputs: none") } fmt.Println(t) return nil }
func (list *StacksList) Run() error { client := cloudformation.NewFromEnv() rsp, e := client.ListStacks(nil) if e != nil { return e } t := gocli.NewTable() for _, s := range rsp.ListStacksResult.Stacks { if !list.IncludeDeleted && s.StackStatus == "DELETE_COMPLETE" { continue } parts := []interface{}{s.StackName, s.StackStatus, s.CreationTime.Format(time.RFC3339)} if list.Full { parts = append(parts, s.StackId) } t.Add(parts...) } fmt.Println(t) return nil }
type StacksDelete struct { Name string `cli:"arg required"` } func (d *StacksDelete) Run() error { logger.Printf("deleting stack %q", d.Name) return client.DeleteStack(d.Name) } type StacksList struct { IncludeDeleted bool `cli:"opt --deleted"` Full bool `cli:"opt --full"` } var client = cloudformation.NewFromEnv() func (list *StacksList) Run() error { rsp, e := client.ListStacks(nil) if e != nil { return e } t := gocli.NewTable() for _, s := range rsp.ListStacksResult.Stacks { if !list.IncludeDeleted && s.StackStatus == "DELETE_COMPLETE" { continue } parts := []interface{}{s.StackName, s.StackStatus, s.CreationTime.Format(time.RFC3339)} if list.Full { parts = append(parts, s.StackId) }
func (d *StacksDelete) Run() error { client := cloudformation.NewFromEnv() logger.Printf("deleting stack %q", d.Name) return client.DeleteStack(d.Name) }