Skip to content

Commit

Permalink
feat(port-forward): added port-forward daemon
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveRuble committed Nov 13, 2020
1 parent f9dad88 commit a1e5cda
Show file tree
Hide file tree
Showing 14 changed files with 1,031 additions and 20 deletions.
7 changes: 6 additions & 1 deletion cmd/helpers_render.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ func renderOutput(out interface{}, columns ...string) error {
}

func printOutput(out interface{}, columns ...string) error {
return printOutputWithDefaultFormat("y", out, columns...)
}

func printOutputWithDefaultFormat(defaultFormat string, out interface{}, columns ...string) error {

format := viper.GetString(ArgGlobalOutput)

if format == "" {
format = "y"
format = defaultFormat
}

formatKey := strings.ToLower(format[0:1])

switch formatKey {
Expand Down
1 change: 1 addition & 0 deletions cmd/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func init() {
// kubeCmd represents the kube command
var kubeCmd = &cobra.Command{
Use: "kube {kube-layout}",
Aliases: []string{"k"},
Args: cobra.ExactArgs(1),
Short: "Group of commands wrapping kubectl.",
Long: `You must have the cluster set in kubectl.`,
Expand Down
284 changes: 284 additions & 0 deletions cmd/kube_port_forward.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
package cmd

import (
"fmt"
"github.com/naveego/bosun/pkg/cli"
"github.com/naveego/bosun/pkg/kube/portforward"
"github.com/naveego/bosun/pkg/yaml"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"io/ioutil"
"os"
"os/signal"
"path/filepath"
"sort"
)

// kubeCmd represents the kube command
var kubePortForwardCmd = addCommand(kubeCmd, &cobra.Command{
Use: "port-forward",
Aliases: []string{"pf"},
Short: "Group of commands for managing port forwarding.",
})

var kubePortForwardDaemon = addCommand(kubePortForwardCmd, &cobra.Command{
Use: "daemon",
Short: "Runs the port-forwarding daemon",
RunE: func(cmd *cobra.Command, args []string) error {

dir := filepath.Join(filepath.Dir(viper.GetString(ArgBosunConfigFile)), "port-forwards")
if len(args) > 0 {
dir = args[0]
}

daemon, err := portforward.NewDaemon(dir)
if err != nil {
return err
}

err = daemon.Start()
if err != nil {
return err
}

signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)

<-signalChan
fmt.Println("Received an interrupt, stopping services...")

return daemon.Stop()
},
})

var kubePortForwardState = addCommand(kubePortForwardCmd, &cobra.Command{
Use: "state",
Aliases: []string{"show","list", "ls"},
Short: "Reports on state of port forwards",
RunE: func(cmd *cobra.Command, args []string) error {
var err error

controller, err := getKubePortForwardController(args)
if err != nil {
return err
}

state, err := controller.GetState()
if err != nil {
return err
}

if state.Error != "" {
return errors.New(state.Error)
}


return printOutputWithDefaultFormat("table", state)
},
})

var kubePortForwardStart = addCommand(kubePortForwardCmd, &cobra.Command{
Use: "start [name]",
Short: "Starts a port forward task",
RunE: func(cmd *cobra.Command, args []string) error {
var err error

controller, err := getKubePortForwardController(args)
if err != nil {
return err
}


var name string
switch len(args){
case 1:
name = args[0]
default:
state, stateErr := controller.GetState()
if stateErr != nil {
return stateErr
}

var names []string
for n, s := range state.Ports {
if !s.Config.Active {
names = append(names, n)
}
}
sort.Strings(names)
if len(names) == 0{
return errors.New("all port-forwards are running")
}

name = cli.RequestChoice("Choose a port-forward to start", names...)
}

err = controller.StartPortForward(name)
return err
},
})

var kubePortForwardStop = addCommand(kubePortForwardCmd, &cobra.Command{
Use: "stop [name]",
Short: "Stops a port forward task",
RunE: func(cmd *cobra.Command, args []string) error {
var err error

controller, err := getKubePortForwardController(args)
if err != nil {
return err
}


var name string
switch len(args){
case 1:
name = args[0]
default:
state, stateErr := controller.GetState()
if stateErr != nil {
return stateErr
}

var names []string
for n, s := range state.Ports {
if s.Config.Active {
names = append(names, n)
}
}
sort.Strings(names)
if len(names) == 0{
return errors.New("no port-forwards running")
}

name = cli.RequestChoice("Choose a port-forward to stop", names...)
}

err = controller.StopPortForward(name)
return err
},
})

func getKubePortForwardController(args []string) (*portforward.Controller, error) {

dir := filepath.Join(filepath.Dir(viper.GetString(ArgBosunConfigFile)), "port-forwards")

controller, err := portforward.NewController(dir)
return controller, err
}

var kubePortForwardAdd = addCommand(kubePortForwardCmd, &cobra.Command{
Use: "add {name} [args...]",
Args: cobra.MinimumNArgs(1),
Short: "Adds a port-forward to the daemon",
RunE: func(cmd *cobra.Command, args []string) error {
var err error

controller, err := getKubePortForwardController(args)
if err != nil {
return err
}

name := args[0]

var portForwardConfig portforward.PortForwardConfig

if len(args) > 1 {
portForwardConfig.Args = args[1:]
} else {
tempFile, _ := ioutil.TempFile(os.TempDir(), "port-forward-*.yaml")

b, _ := yaml.Marshal(portForwardConfig)
_, err = tempFile.Write(b)
if err != nil {
return err
}

err = tempFile.Close()
if err != nil {
return err
}

err = cli.Edit(tempFile.Name())
if err != nil {
return err
}

err = yaml.LoadYaml(tempFile.Name(), &portForwardConfig)
if err != nil {
return err
}
}

err = controller.AddPortForward(name, portForwardConfig)

return err
},
})

var kubePortForwardEdit = addCommand(kubePortForwardCmd, &cobra.Command{
Use: "edit [name]",
Short: "Edit a port-forward",
RunE: func(cmd *cobra.Command, args []string) error {

controller, err := getKubePortForwardController(args)
if err != nil {
return err
}


var name string
switch len(args){
case 1:
name = args[0]
default:
state, stateErr := controller.GetState()
if stateErr != nil {
return stateErr
}

var names []string
for n, s := range state.Ports {
if s.Config.Active {
names = append(names, n)
}
}
sort.Strings(names)
if len(names) == 0{
return errors.New("no port-forwards found")
}

name = cli.RequestChoice("Choose a port-forward to edit", names...)
}

portForwardConfig, err := controller.GetPortForwardConfig(name)

tempFile, _ := ioutil.TempFile(os.TempDir(), "port-forward-*.yaml")

b, _ := yaml.Marshal(portForwardConfig)
_, err = tempFile.Write(b)
if err != nil {
return err
}

err = tempFile.Close()
if err != nil {
return err
}

err = cli.Edit(tempFile.Name())
if err != nil {
return err
}

err = yaml.LoadYaml(tempFile.Name(), &portForwardConfig)
if err != nil {
return err
}

err = controller.AddPortForward(name, *portForwardConfig)

return err
},
})
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func init() {
}

rootCmd.PersistentFlags().String(ArgBosunConfigFile, bosunConfigFile, "Config file for Bosun. You can also set BOSUN_CONFIG.")
rootCmd.PersistentFlags().StringP(ArgGlobalOutput, "o", "yaml", "Output format. Options are `table`, `json`, or `yaml`. Only respected by a some commands.")
rootCmd.PersistentFlags().StringP(ArgGlobalOutput, "o", "", "Output format. Options are `table`, `json`, or `yaml`. Only respected by a some commands.")
rootCmd.PersistentFlags().Bool(ArgGlobalVerbose, false, "Enable verbose logging.")
rootCmd.PersistentFlags().Bool(ArgGlobalTrace, false, "Enable trace logging.")
_ = rootCmd.PersistentFlags().MarkHidden(ArgGlobalTrace)
Expand Down
11 changes: 5 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
github.com/fatih/color v1.7.0
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/fullsailor/pkcs7 v0.0.0-20180613152042-8306686428a5 // indirect
github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7 // indirect
github.com/gammazero/workerpool v0.0.0-20181230203049-86a96b5d5d92 // indirect
Expand All @@ -54,6 +55,7 @@ require (
github.com/go-stomp/stomp v2.0.2+incompatible // indirect
github.com/go-test/deep v1.0.1 // indirect
github.com/gocql/gocql v0.0.0-20181124151448-70385f88b28b // indirect
github.com/gofrs/flock v0.8.0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1 // indirect
Expand Down Expand Up @@ -126,7 +128,7 @@ require (
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/pquerna/otp v1.1.0 // indirect
github.com/prometheus/common v0.2.0
github.com/rapidloop/mybot v0.0.0-20160205033900-2777401b233f
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
github.com/rs/xid v1.2.1
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 // indirect
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec // indirect
Expand All @@ -143,6 +145,7 @@ require (
github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
github.com/vbauerster/mpb/v4 v4.7.0
github.com/x-cray/logrus-prefixed-formatter v0.5.2
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
github.com/xdg/stringprep v1.0.0 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
Expand All @@ -159,6 +162,7 @@ require (
gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa
gopkg.in/ldap.v2 v2.5.1 // indirect
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/ory-am/dockertest.v2 v2.2.3 // indirect
gopkg.in/square/go-jose.v2 v2.3.0 // indirect
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637
Expand All @@ -171,11 +175,6 @@ require (
sigs.k8s.io/controller-runtime v0.4.0
)

replace (
gopkg.in/russross/blackfriday.v2 v2.0.0 => github.com/russross/blackfriday/v2 v2.0.1
gopkg.in/russross/blackfriday.v2 v2.0.1 => github.com/russross/blackfriday/v2 v2.0.1
)

replace (
k8s.io/api => k8s.io/api v0.0.0-20190222213804-5cb15d344471
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628
Expand Down
Loading

0 comments on commit a1e5cda

Please sign in to comment.