Skip to content

Instantly share code, notes, and snippets.

@hongchaodeng
Created April 27, 2022 06:26
Show Gist options
  • Save hongchaodeng/a2c445877f1a9a1b348ccd5a481ca9b1 to your computer and use it in GitHub Desktop.
Save hongchaodeng/a2c445877f1a9a1b348ccd5a481ca9b1 to your computer and use it in GitHub Desktop.
port forward
package main
import (
"io"
"net/http"
"net/url"
"os"
"os/signal"
"syscall"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/portforward"
"k8s.io/client-go/transport/spdy"
"k8s.io/klog/v2"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
)
// NewFactory can generate many kinds of k8s client.
func NewFactory(kubeconfigPath string) cmdutil.Factory {
configFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag().WithDiscoveryBurst(300).WithDiscoveryQPS(50.0)
configFlags.KubeConfig = &kubeconfigPath
return cmdutil.NewFactory(configFlags)
}
func main() {
fac := NewFactory("kubeconfig")
clientSet, err := fac.KubernetesClientSet()
if err != nil {
klog.Fatal("kubernetes clientSet failed.", err)
}
req := clientSet.CoreV1().RESTClient().Post().Namespace("ingress-nginx").
Resource("pods").Name("ingress-nginx-controller-65bd9b5d54-8clj9").SubResource("portforward")
klog.Info(req.URL())
signals := make(chan os.Signal, 1)
StopChannel := make(chan struct{}, 1)
ReadyChannel := make(chan struct{})
defer signal.Stop(signals)
signal.Notify(signals, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL)
go func() {
<-signals
if StopChannel != nil {
close(StopChannel)
}
}()
config, err := fac.ToRESTConfig()
if err != nil {
panic(err)
}
if err := ForwardPorts("POST", req.URL(), config, StopChannel, ReadyChannel); err != nil {
klog.Fatalln(err)
}
}
func ForwardPorts(method string, url *url.URL, config *rest.Config, StopChannel, ReadyChannel chan struct{}) error {
transport, upgrader, err := spdy.RoundTripperFor(config)
if err != nil {
return err
}
address := []string{"0.0.0.0"}
ports := []string{"8080:80"}
IOStreams := struct {
// In think, os.Stdin
In io.Reader
// Out think, os.Stdout
Out io.Writer
// ErrOut think, os.Stderr
ErrOut io.Writer
}{os.Stdin, os.Stdout, os.Stderr}
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
fw, err := portforward.NewOnAddresses(dialer, address, ports, StopChannel, ReadyChannel, IOStreams.Out, IOStreams.ErrOut)
if err != nil {
return err
}
return fw.ForwardPorts()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment