Skip to content

Commit

Permalink
Add some support for custom proxies
Browse files Browse the repository at this point in the history
New flags added for
- customProxyPort
- disableReadinessProbe
- customProxyReadinessPath
- env vars

Also updated viper to include bug fix for StringArrayP
spf13/viper#398

Signed-off-by: stoobmmelier <>
  • Loading branch information
stoobmmelier committed Jul 20, 2021
1 parent ebf9a56 commit 49c12fb
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 60 deletions.
16 changes: 16 additions & 0 deletions cmd/kubectl-tap/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ func main() {
onCmd.Flags().Bool("port-forward", false, "enable to automatically kubctl port-forward to services")
onCmd.Flags().Bool("browser", false, "enable to open browser windows to service and proxy. Also enables --port-forward")
onCmd.Flags().String("protocol", "http", "specify a protocol. Supported protocols: [ http ]")
onCmd.Flags().String("custom-proxy-port", "", "target Service port for the custom proxy")
onCmd.Flags().Bool("disable-readiness-probe", false, "enable if readiness probe is to be disabled")
onCmd.Flags().String("custom-proxy-readiness-path", "", "Path for the custom proxy's readiness probe")
onCmd.Flags().StringArrayP("env", "e", []string{}, "Environment variables to inject into the proxy container")

rootCmd.AddCommand(versionCmd, onCmd, offCmd, listCmd)

Expand Down Expand Up @@ -109,6 +113,18 @@ func bindTapFlags(cmd *cobra.Command, _ []string) error {
if err := viper.BindPFlag("protocol", cmd.Flags().Lookup("protocol")); err != nil {
return err
}
if err := viper.BindPFlag("customProxyPort", cmd.Flags().Lookup("custom-proxy-port")); err != nil {
return err
}
if err := viper.BindPFlag("disableReadinessProbe", cmd.Flags().Lookup("disable-readiness-probe")); err != nil {
return err
}
if err := viper.BindPFlag("customProxyReadinessPath", cmd.Flags().Lookup("custom-proxy-readiness-path")); err != nil {
return err
}
if err := viper.BindPFlag("envVars", cmd.Flags().Lookup("env")); err != nil {
return err
}
return nil
}

Expand Down
81 changes: 73 additions & 8 deletions cmd/kubectl-tap/tap.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ func NewTapCommand(client kubernetes.Interface, config *rest.Config, viper *vipe
https := viper.GetBool("https")
portForward := viper.GetBool("portForward")
openBrowser := viper.GetBool("browser")
customProxyPort := viper.GetInt("customProxyPort")
disableReadinessProbe := viper.GetBool("disableReadinessProbe")
customProxyReadinessPath := viper.GetString("customProxyReadinessPath")

if openBrowser {
portForward = true
Expand Down Expand Up @@ -316,6 +319,31 @@ func NewTapCommand(client kubernetes.Interface, config *rest.Config, viper *vipe
sidecar.Image = image
sidecar.Args = commandArgs

if customProxyPort != 0 {
sidecar.Ports[1].ContainerPort = int32(customProxyPort)
sidecar.ReadinessProbe.Handler.HTTPGet.Port = intstr.FromInt(customProxyPort)
}

if disableReadinessProbe == true {
sidecar.ReadinessProbe = nil
} else {
if customProxyReadinessPath != "" {
sidecar.ReadinessProbe.Handler.HTTPGet.Path = customProxyReadinessPath
}
}

sidecarEnvVars := []v1.EnvVar{}
envVars := viper.GetStringSlice("envVars")

for _, envVar := range envVars {
kv := strings.SplitN(envVar, "=", 2)
key := kv[0]
val := kv[1]
sidecarEnvVars = append(sidecarEnvVars, v1.EnvVar{Name: key, Value: val})
}

sidecar.Env = sidecarEnvVars

// Apply the Deployment configuration
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
dpl.Spec.Template.Spec.Containers = append(dpl.Spec.Template.Spec.Containers, sidecar)
Expand All @@ -338,7 +366,7 @@ func NewTapCommand(client kubernetes.Interface, config *rest.Config, viper *vipe

// Tap the Service to redirect the incoming traffic to our proxy, which is configured to redirect
// to the original port.
if err := tapSvc(servicesClient, targetSvcName, targetSvcPort); err != nil {
if err := tapSvc(servicesClient, targetSvcName, targetSvcPort, customProxyPort); err != nil {
fmt.Fprintln(cmd.OutOrStdout(), "Error modifying Service, reverting tap...")
_ = NewUntapCommand(client, viper)(cmd, args)
return err
Expand Down Expand Up @@ -453,25 +481,51 @@ func NewTapCommand(client kubernetes.Interface, config *rest.Config, viper *vipe
Host: strings.TrimPrefix(strings.TrimPrefix(config.Host, `http://`), `https://`),
},
)
fw, err := portforward.New(dialer,
[]string{

portForwarderPorts := []string{}

if customProxyPort != 0 {
portForwarderPorts = []string{
fmt.Sprintf("%s:%s", strconv.Itoa(customProxyPort), strconv.Itoa(customProxyPort)),
fmt.Sprintf("%s:%s", "4000", strconv.Itoa(int(kubetapProxyListenPort))),
}
} else {
portForwarderPorts = []string{
fmt.Sprintf("%s:%s", strconv.Itoa(kubetapProxyWebInterfacePort), strconv.Itoa(kubetapProxyWebInterfacePort)),
fmt.Sprintf("%s:%s", "4000", strconv.Itoa(int(kubetapProxyListenPort))),
}, stopCh, readyCh, bout, berr)
}
}

fw, err := portforward.New(dialer, portForwarderPorts, stopCh, readyCh, bout, berr)
if err != nil {
return err
}

proxyPort := ""

if customProxyPort != 0 {
proxyPort = strconv.Itoa(int(customProxyPort))
} else {
proxyPort = strconv.Itoa(int(kubetapProxyWebInterfacePort))
}

fmt.Fprintf(cmd.OutOrStdout(), "\nPort-Forwards:\n\n")
fmt.Fprintf(cmd.OutOrStdout(), " %s - http://127.0.0.1:%s\n", proxy.String(), strconv.Itoa(int(kubetapProxyWebInterfacePort)))
fmt.Fprintf(cmd.OutOrStdout(), " %s - http://127.0.0.1:%s\n", proxy.String(), proxyPort)

if https {
fmt.Fprintf(cmd.OutOrStdout(), " %s - https://127.0.0.1:%s\n\n", targetSvcName, "4000")
} else {
fmt.Fprintf(cmd.OutOrStdout(), " %s - http://127.0.0.1:%s\n\n", targetSvcName, "4000")
}

if openBrowser {
go func() {
time.Sleep(2 * time.Second)
_ = browser.OpenURL("http://127.0.0.1:" + strconv.Itoa(int(kubetapProxyWebInterfacePort)))
if customProxyPort != 0 {
_ = browser.OpenURL("http://127.0.0.1:" + strconv.Itoa(int(customProxyPort)))
} else {
_ = browser.OpenURL("http://127.0.0.1:" + strconv.Itoa(int(kubetapProxyWebInterfacePort)))
}
if https {
_ = browser.OpenURL("https://127.0.0.1:" + "4000")
} else {
Expand Down Expand Up @@ -628,7 +682,7 @@ func kubetapPod(podClient corev1.PodInterface, deploymentName string) (v1.Pod, e
}

// tapSvc modifies a target port to point to a new proxy service.
func tapSvc(svcClient corev1.ServiceInterface, svcName string, targetPort int32) error {
func tapSvc(svcClient corev1.ServiceInterface, svcName string, targetPort int32, customProxyPort int) error {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
svc, getErr := svcClient.Get(context.TODO(), svcName, metav1.GetOptions{})
if getErr != nil {
Expand Down Expand Up @@ -666,6 +720,12 @@ func tapSvc(svcClient corev1.ServiceInterface, svcName string, targetPort int32)
Port: kubetapProxyWebInterfacePort,
TargetPort: intstr.FromInt(int(kubetapProxyWebInterfacePort)),
}

if customProxyPort != 0 {
proxySvcPort.Port = int32(customProxyPort)
proxySvcPort.TargetPort = intstr.FromInt(int(customProxyPort))
}

svc.Spec.Ports = append(svc.Spec.Ports, proxySvcPort)

// then do the swap and build a new ports list
Expand All @@ -675,7 +735,12 @@ func tapSvc(svcClient corev1.ServiceInterface, svcName string, targetPort int32)
if sp.Name == "" {
sp.Name = kubetapPortName
}
sp.TargetPort = intstr.FromInt(kubetapProxyListenPort)

if customProxyPort != 0 {
sp.TargetPort = intstr.FromInt(customProxyPort)
} else {
sp.TargetPort = intstr.FromInt(kubetapProxyListenPort)
}
}
servicePorts = append(servicePorts, sp)
}
Expand Down
13 changes: 1 addition & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,13 @@ module github.com/soluble-ai/kubetap
go 1.14

require (
github.com/magiconair/properties v1.8.4 // indirect
github.com/mattn/go-runewidth v0.0.10 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4
github.com/rivo/uniseg v0.2.0 // indirect
github.com/schollz/progressbar/v3 v3.7.3
github.com/spf13/afero v1.5.1 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.1.1
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 // indirect
golang.org/x/text v0.3.5 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/api v0.20.2
k8s.io/apimachinery v0.20.2
k8s.io/cli-runtime v0.20.2
Expand Down
Loading

0 comments on commit 49c12fb

Please sign in to comment.