Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some support for custom proxies #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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