Skip to content

Commit

Permalink
feat: WithForwardersEmbedConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
anthhub committed Aug 3, 2021
1 parent 8a0abfa commit 4a10c8b
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 76 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
kubeconfig
.DS_Store
40 changes: 40 additions & 0 deletions example/embedconfig/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
"context"
_ "embed"
"fmt"

"github.com/anthhub/forwarder"
)

//go:embed kubeconfig
var kubeconfigBytes []byte

func main() {
options := []*forwarder.Option{
{
// LocalPort: 8080,
// RemotePort: 80,
ServiceName: "my-nginx-svc",
},
}

ret, err := forwarder.WithForwardersEmbedConfig(context.Background(), options, kubeconfigBytes)
if err != nil {
panic(err)
}
// remember to close the forwarding
defer ret.Close()
// wait forwarding ready
// the remote and local ports are listed
ports, err := ret.Ready()
if err != nil {
panic(err)
}
fmt.Printf("ports: %+v\n", ports)
// ...

// if you want to block the goroutine and listen IOStreams close signal, you can do as following:
ret.Wait()
}
3 changes: 2 additions & 1 deletion example/httpserver.go → example/httpserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package main

import (
"context"

_ "embed"
"fmt"
"net/http"

Expand Down Expand Up @@ -52,6 +52,7 @@ func main() {
if err != nil {
panic(err)
}

// remember to close the forwarding
defer ret.Close()
// wait forwarding ready
Expand Down
68 changes: 62 additions & 6 deletions forwarder.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,50 @@ import (
"syscall"

"golang.org/x/sync/errgroup"

"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/tools/clientcmd"
restclient "k8s.io/client-go/rest"
clientcmd "k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/tools/portforward"
"k8s.io/client-go/transport/spdy"
)

var once sync.Once

// It is to forward port whith kubeconfig bytes.
func WithForwardersEmbedConfig(ctx context.Context, options []*Option, kubeconfigBytes []byte) (*Result, error) {
kubeconfigGetter := func() (*clientcmdapi.Config, error) {
config, err := shimLoadConfig(kubeconfigBytes)
if err != nil {
return nil, err
}

return config, nil
}
config, err := clientcmd.BuildConfigFromKubeconfigGetter("", kubeconfigGetter)
if err != nil {
return nil, err
}

return forwarders(ctx, options, config)
}

// It is to forward port for k8s cloud services.
func WithForwarders(ctx context.Context, options []*Option, kubeconfig string) (*Result, error) {
if kubeconfig == "" {
kubeconfig = "~/.kube/config"
func WithForwarders(ctx context.Context, options []*Option, kubeconfigPath string) (*Result, error) {
if kubeconfigPath == "" {
kubeconfigPath = "~/.kube/config"
}

config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
if err != nil {
return nil, err
}

return forwarders(ctx, options, config)
}

// It is to forward port for k8s cloud services.
func forwarders(ctx context.Context, options []*Option, config *restclient.Config) (*Result, error) {
newOptions, err := parseOptions(options)
if err != nil {
return nil, err
Expand Down Expand Up @@ -118,6 +142,7 @@ func WithForwarders(ctx context.Context, options []*Option, kubeconfig string) (
return ret, nil
}

// It is to forward port, and return the forwarder.
func portForwardAPod(req *portForwardAPodRequest) (*portforward.PortForwarder, error) {
path := fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/portforward",
req.Pod.Namespace, req.Pod.Name)
Expand All @@ -142,3 +167,34 @@ func portForwardAPod(req *portForwardAPodRequest) (*portforward.PortForwarder, e

return fw, nil
}

// It is to transform kubeconfig bytes to clientcmdapi config.
func shimLoadConfig(kubeconfigBytes []byte) (*clientcmdapi.Config, error) {
config, err := clientcmd.Load(kubeconfigBytes)
if err != nil {
return nil, err
}

// set LocationOfOrigin on every Cluster, User, and Context
for key, obj := range config.AuthInfos {
config.AuthInfos[key] = obj
}
for key, obj := range config.Clusters {
config.Clusters[key] = obj
}
for key, obj := range config.Contexts {
config.Contexts[key] = obj
}

if config.AuthInfos == nil {
config.AuthInfos = map[string]*clientcmdapi.AuthInfo{}
}
if config.Clusters == nil {
config.Clusters = map[string]*clientcmdapi.Cluster{}
}
if config.Contexts == nil {
config.Contexts = map[string]*clientcmdapi.Context{}
}

return config, nil
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
module github.com/anthhub/forwarder

go 1.15
go 1.16

require (
github.com/gin-gonic/gin v1.7.2 // indirect
github.com/namsral/flag v1.7.4-pre // indirect
github.com/gin-gonic/gin v1.7.3
github.com/golang/glog v0.0.0-20210429001901-424d2337a529
github.com/namsral/flag v1.7.4-pre
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
k8s.io/api v0.21.3
k8s.io/apimachinery v0.21.3
k8s.io/cli-runtime v0.21.3
k8s.io/client-go v0.21.3
k8s.io/kubectl v0.21.3 // indirect
)
Loading

0 comments on commit 4a10c8b

Please sign in to comment.