github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/internal/commands/tunnel_down.go (about) 1 package commands 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/fs" 7 "os/exec" 8 "syscall" 9 10 "github.com/hazelops/ize/internal/config" 11 "github.com/pterm/pterm" 12 "github.com/sirupsen/logrus" 13 "github.com/spf13/cobra" 14 ) 15 16 var explainTunnelDownTmpl = ` 17 # Change to the dir and send an exit request 18 (cd {{.EnvDir}} && $(aws ssm get-parameter --name "/{{.Env}}/terraform-output" --with-decryption | jq -r '.Parameter.Value' | base64 -d | jq -r '.cmd.value.tunnel.down')) 19 ` 20 21 type TunnelDownOptions struct { 22 Config *config.Project 23 Explain bool 24 } 25 26 func NewTunnelDownOptions(project *config.Project) *TunnelDownOptions { 27 return &TunnelDownOptions{ 28 Config: project, 29 } 30 } 31 32 func NewCmdTunnelDown(project *config.Project) *cobra.Command { 33 o := NewTunnelDownOptions(project) 34 35 cmd := &cobra.Command{ 36 Use: "down", 37 Short: "Close tunnel", 38 Long: "Close tunnel", 39 RunE: func(cmd *cobra.Command, args []string) error { 40 cmd.SilenceUsage = true 41 42 if o.Explain { 43 err := o.Config.Generate(explainTunnelDownTmpl, nil) 44 if err != nil { 45 return err 46 } 47 48 return nil 49 } 50 51 err := o.Complete() 52 if err != nil { 53 return err 54 } 55 56 err = o.Validate() 57 if err != nil { 58 return err 59 } 60 61 err = o.Run() 62 if err != nil { 63 return err 64 } 65 66 return nil 67 }, 68 } 69 70 cmd.Flags().BoolVar(&o.Explain, "explain", false, "bash alternative shown") 71 72 return cmd 73 } 74 75 func (o *TunnelDownOptions) Complete() error { 76 return nil 77 } 78 79 func (o *TunnelDownOptions) Validate() error { 80 if len(o.Config.Env) == 0 { 81 return fmt.Errorf("env must be specified") 82 } 83 84 return nil 85 } 86 87 func (o *TunnelDownOptions) Run() error { 88 c := exec.Command( 89 "ssh", "-S", "bastion.sock", "-O", "exit", "", 90 ) 91 92 if o.Config.LogLevel == "debug" { 93 c.Args = append(c.Args, "-vvv") 94 } 95 96 out := &bytes.Buffer{} 97 c.Stdout = out 98 c.Stderr = out 99 c.Dir = o.Config.EnvDir 100 101 err := c.Run() 102 if err != nil { 103 patherr, ok := err.(*fs.PathError) 104 if ok { 105 return fmt.Errorf("unable to access folder '%s': %w", c.Dir, patherr.Err) 106 } 107 exiterr := err.(*exec.ExitError) 108 status := exiterr.Sys().(syscall.WaitStatus) 109 if status.ExitStatus() != 255 { 110 logrus.Debug(out.String()) 111 return fmt.Errorf("unable to bring the tunnel down: %w", err) 112 } 113 return fmt.Errorf("unable to bring the tunnel down: tunnel is not active") 114 } 115 116 pterm.Success.Println("Tunnel is down!") 117 118 return nil 119 }