github.com/orangenpresse/up@v0.6.0/internal/cli/stack/stack.go (about) 1 package stack 2 3 import ( 4 "fmt" 5 6 "github.com/pkg/errors" 7 "github.com/tj/kingpin" 8 "github.com/tj/survey" 9 10 "github.com/apex/up/internal/cli/root" 11 "github.com/apex/up/internal/stats" 12 "github.com/apex/up/internal/util" 13 ) 14 15 func init() { 16 cmd := root.Command("stack", "Stack resource management.") 17 18 cmd.Example(`up stack`, "Show status of the stack resources.") 19 cmd.Example(`up stack plan`, "Show resource changes.") 20 cmd.Example(`up stack apply`, "Apply resource changes.") 21 cmd.Example(`up stack delete`, "Delete the stack resources.") 22 23 plan(cmd) 24 apply(cmd) 25 delete(cmd) 26 status(cmd) 27 } 28 29 // plan changes. 30 func plan(cmd *kingpin.Cmd) { 31 c := cmd.Command("plan", "Plan configuration changes.") 32 c.Example(`up stack plan`, "Show changes planned.") 33 34 c.Action(func(_ *kingpin.ParseContext) error { 35 c, p, err := root.Init() 36 if err != nil { 37 return errors.Wrap(err, "initializing") 38 } 39 40 stats.Track("Plan Stack", nil) 41 42 // TODO: multi-region 43 return p.PlanStack(c.Regions[0]) 44 }) 45 } 46 47 // apply changes. 48 func apply(cmd *kingpin.Cmd) { 49 c := cmd.Command("apply", "Apply configuration changes.") 50 c.Example(`up stack apply`, "Apply the changes of the previous plan.") 51 52 c.Action(func(_ *kingpin.ParseContext) error { 53 c, p, err := root.Init() 54 if err != nil { 55 return errors.Wrap(err, "initializing") 56 } 57 58 stats.Track("Apply Stack", map[string]interface{}{ 59 "dns_zone_count": len(c.DNS.Zones), 60 "stage_count": len(c.Stages.List()), 61 "stage_domain_count": len(c.Stages.Domains()), 62 }) 63 64 // TODO: multi-region 65 return p.ApplyStack(c.Regions[0]) 66 }) 67 } 68 69 // delete resources. 70 func delete(cmd *kingpin.Cmd) { 71 c := cmd.Command("delete", "Delete configured resources.") 72 c.Example(`up stack delete`, "Delete stack with confirmation prompt.") 73 c.Example(`up stack delete --force`, "Delete stack without confirmation prompt.") 74 c.Example(`up stack delete --async`, "Don't wait for deletion to complete.") 75 c.Example(`up stack delete -fa`, "Force asynchronous deletion.") 76 77 force := c.Flag("force", "Skip the confirmation prompt.").Short('f').Bool() 78 async := c.Flag("async", "Perform deletion asynchronously.").Short('a').Bool() 79 80 c.Action(func(_ *kingpin.ParseContext) error { 81 c, p, err := root.Init() 82 if err != nil { 83 return errors.Wrap(err, "initializing") 84 } 85 86 wait := !*async 87 defer util.Pad()() 88 89 stats.Track("Delete Stack", map[string]interface{}{ 90 "force": *force, 91 "wait": wait, 92 }) 93 94 if *force { 95 // TODO: multi-region 96 return p.DeleteStack(c.Regions[0], wait) 97 } 98 99 prompt := &survey.Confirm{ 100 Message: fmt.Sprintf("Really destroy stack %q?", c.Name), 101 } 102 103 var ok bool 104 if err := survey.AskOne(prompt, &ok, nil); err != nil { 105 return err 106 } 107 108 if !ok { 109 util.LogPad("Aborted") 110 return nil 111 } 112 113 return p.DeleteStack(c.Regions[0], wait) 114 }) 115 } 116 117 // status of the stack. 118 func status(cmd *kingpin.Cmd) { 119 c := cmd.Command("status", "Show status of resources.").Default() 120 121 c.Action(func(_ *kingpin.ParseContext) error { 122 c, p, err := root.Init() 123 if err != nil { 124 return errors.Wrap(err, "initializing") 125 } 126 127 stats.Track("Show Stack", nil) 128 129 // TODO: multi-region 130 return p.ShowStack(c.Regions[0]) 131 }) 132 }