Skip to content

Commit

Permalink
Merge pull request #175 from ndj888/feature/port-map
Browse files Browse the repository at this point in the history
feat: add port mapping
  • Loading branch information
cjimti authored Mar 8, 2021
2 parents 78b485b + 6060008 commit ef08034
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Examples:
kubefwd svc -n default -n the-project
kubefwd svc -n default -d internal.example.com
kubefwd svc -n the-project -x prod-cluster
kubefwd svc -n the-project -m 80:8080 -m 443:1443
Flags:
Expand All @@ -141,6 +142,7 @@ Flags:
-c, --kubeconfig string absolute path to a kubectl config file
-n, --namespace strings Specify a namespace. Specify multiple namespaces by duplicating this argument.
-l, --selector string Selector (label query) to filter on; supports '=', '==', '!=' (e.g. -l key1=value1,key2=value2) and 'in' (e.g. -l "app in (value1, value2)").
-m, --mapping strings Specify a port mapping. Specify multiple mapping by duplicating this argument.
-v, --verbose Verbose output.
```
Expand Down
4 changes: 3 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ Examples:
kubefwd svc -n default -n the-project
kubefwd svc -n default -d internal.example.com
kubefwd svc -n the-project -x prod-cluster
kubefwd svc -n the-project -m 80:8080 -m 443:1443
Flags:
-x, --context strings specify a context to override the current context
Expand All @@ -138,6 +139,7 @@ Flags:
-c, --kubeconfig string absolute path to a kubectl config fil (default "/Users/cjimti/.kube/config")
-n, --namespace strings Specify a namespace. Specify multiple namespaces by duplicating this argument.
-l, --selector string Selector (label query) to filter on; supports '=', '==', and '!=' (e.g. -l key1=value1,key2=value2).
-m, --mapping strings Specify a port mapping. Specify multiple mapping by duplicating this argument.
-v, --verbose Verbose output.
```
Expand Down
4 changes: 3 additions & 1 deletion cmd/kubefwd/kubefwd.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ func newRootCmd() *cobra.Command {
" kubefwd svc -n the-project\n" +
" kubefwd svc -n the-project -l env=dev,component=api\n" +
" kubefwd svc -n default -l \"app in (ws, api)\"\n" +
" kubefwd svc -n default -n the-project\n",
" kubefwd svc -n default -n the-project\n" +
" kubefwd svc -n the-project -m 80:8080 -m 443:1443\n",

Long: globalUsage,
}

Expand Down
23 changes: 22 additions & 1 deletion cmd/kubefwd/services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"os"
"os/signal"
"strings"
"sync"
"syscall"
"time"
Expand Down Expand Up @@ -53,6 +54,7 @@ var namespaces []string
var contexts []string
var verbose bool
var domain string
var mappings []string

func init() {
// override error output from k8s.io/apimachinery/pkg/util/runtime
Expand All @@ -67,6 +69,7 @@ func init() {
Cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on; supports '=', '==', and '!=' (e.g. -l key1=value1,key2=value2).")
Cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output.")
Cmd.Flags().StringVarP(&domain, "domain", "d", "", "Append a pseudo domain name to generated host names.")
Cmd.Flags().StringSliceVarP(&mappings, "mapping", "m", []string{}, "Specify a port mapping. Specify multiple mapping by duplicating this argument.")

}

Expand All @@ -80,7 +83,8 @@ var Cmd = &cobra.Command{
" kubefwd svc -n default -l \"app in (ws, api)\"\n" +
" kubefwd svc -n default -n the-project\n" +
" kubefwd svc -n default -d internal.example.com\n" +
" kubefwd svc -n the-project -x prod-cluster\n",
" kubefwd svc -n the-project -x prod-cluster\n" +
" kubefwd svc -n the-project -m 80:8080 -m 443:1443\n",
Run: runCmd,
}

Expand Down Expand Up @@ -288,6 +292,7 @@ Try:
NamespaceN: ii,
Domain: domain,
ManualStopChannel: stopListenCh,
PortMapping: mappings,
}

go func(npo NamespaceOpts) {
Expand Down Expand Up @@ -336,6 +341,8 @@ type NamespaceOpts struct {

// Domain is specified by the user and used in place of .local
Domain string
// meaning any source port maps to target port.
PortMapping []string

ManualStopChannel chan struct{}
}
Expand Down Expand Up @@ -410,6 +417,7 @@ func (opts *NamespaceOpts) AddServiceHandler(obj interface{}) {
PortForwards: make(map[string]*fwdport.PortForwardOpts),
SyncDebouncer: debounce.New(5 * time.Second),
DoneChannel: make(chan struct{}),
PortMap: opts.ParsePortMap(mappings),
}

// Add the service to the catalog of services being forwarded
Expand All @@ -435,3 +443,16 @@ func (opts *NamespaceOpts) UpdateServiceHandler(_ interface{}, new interface{})
log.Printf("update service %s.", key)
}
}

// parse string port to PortMap
func (opts *NamespaceOpts) ParsePortMap(mappings []string) *[]fwdservice.PortMap {
var portList []fwdservice.PortMap
if mappings == nil {
return nil
}
for _, s := range mappings {
portInfo := strings.Split(s, ":")
portList = append(portList, fwdservice.PortMap{SourcePort: portInfo[0], TargetPort: portInfo[1]})
}
return &portList
}
34 changes: 31 additions & 3 deletions pkg/fwdservice/fwdservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ type ServiceFWD struct {
// while normally only a single pod is forwarded.
Headless bool

LastSyncedAt time.Time // When was the set of pods last synced
LastSyncedAt time.Time // When was the set of pods last synced
PortMap *[]PortMap // port map array.

// Use debouncer for listing pods so we don't hammer the k8s when a bunch of changes happen at once
SyncDebouncer func(f func())
Expand All @@ -70,6 +71,15 @@ type ServiceFWD struct {
DoneChannel chan struct{} // After shutdown is complete, this channel will be closed
}

/**
add port map
@url https://github.com/txn2/kubefwd/issues/121
*/
type PortMap struct {
SourcePort string
TargetPort string
}

// String representation of a ServiceFWD returns a unique name
// in the form SERVICE_NAME.NAMESPACE.CONTEXT
func (svcFwd *ServiceFWD) String() string {
Expand Down Expand Up @@ -252,8 +262,12 @@ func (svcFwd *ServiceFWD) LoopPodsToForward(pods []v1.Pod, includePodNameInHost
}

podPort = port.TargetPort.String()
localPort := strconv.Itoa(int(port.Port))

localPort := svcFwd.getPortMap(port.Port)
p, err := strconv.ParseInt(localPort, 10, 32)
if err != nil {
log.Fatal(err)
}
port.Port = int32(p)
if _, err := strconv.Atoi(podPort); err != nil {
// search a pods containers for the named port
if namedPodPort, ok := portSearch(podPort, pod.Spec.Containers); ok {
Expand Down Expand Up @@ -362,3 +376,17 @@ func portSearch(portName string, containers []v1.Container) (string, bool) {

return "", false
}

// port exist port map return
func (svcFwd *ServiceFWD) getPortMap(port int32) string {
p := strconv.Itoa(int(port))
if svcFwd.PortMap != nil {
for _, portMapInfo := range *svcFwd.PortMap {
if p == portMapInfo.SourcePort {
//use map port
return portMapInfo.TargetPort
}
}
}
return p
}

0 comments on commit ef08034

Please sign in to comment.