Skip to content

Commit

Permalink
feat: Support to serve http via socket
Browse files Browse the repository at this point in the history
  • Loading branch information
orangedeng committed Oct 9, 2024
1 parent db2728f commit 04c38da
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.0
replace k8s.io/client-go => k8s.io/client-go v0.30.1

require (
github.com/Microsoft/go-winio v0.6.2
github.com/gorilla/mux v1.8.1
github.com/rancher/apiserver v0.0.0-20240708202538-39a6f2535146
github.com/rancher/steve v0.0.0-20240911190153-79304d93b49b
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
Expand Down
6 changes: 6 additions & 0 deletions internal/config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var InsecureSkipTLSVerify bool
var SystemDefaultRegistry string
var APIUIVersion = "1.1.11"
var ShellPodImage string
var BindAddress string

func Flags() []cli.Flag {
return []cli.Flag{
Expand All @@ -30,5 +31,10 @@ func Flags() []cli.Flag {
Destination: &APIUIVersion,
Value: APIUIVersion,
},
cli.StringFlag{
Name: "bind-address",
Destination: &BindAddress,
Usage: "Bind address with url format. The supported schemes are unix, tcp and namedpipe, e.g. unix:///path/to/kube-explorer.sock or namedpipe://./pipe/kube-explorer",
},
}
}
51 changes: 51 additions & 0 deletions internal/server/listener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package server

import (
"context"
"log"
"net"
"net/http"

"github.com/cnrancher/kube-explorer/internal/config"
dynamicserver "github.com/rancher/dynamiclistener/server"
"github.com/rancher/steve/pkg/server"
"github.com/sirupsen/logrus"
)

func Serve(ctx context.Context, server *server.Server) error {
listener, ipOrPath, err := ensureListener()
if err != nil {
return err
}
if listener != nil {
return serveSocket(ctx, ipOrPath, listener, server)
}
return server.ListenAndServe(ctx, config.Steve.HTTPSListenPort, config.Steve.HTTPListenPort, &dynamicserver.ListenOpts{
BindHost: ipOrPath,
})
}

func serveSocket(ctx context.Context, socketPath string, listener net.Listener, handler http.Handler) error {
logger := logrus.StandardLogger()
errorLog := log.New(logger.WriterLevel(logrus.DebugLevel), "", log.LstdFlags)
socketServer := &http.Server{
Handler: handler,
ErrorLog: errorLog,
BaseContext: func(_ net.Listener) context.Context {
return ctx
},
}
go func() {
logrus.Infof("Listening on %s", socketPath)
err := socketServer.Serve(listener)
if err != http.ErrServerClosed && err != nil {
logrus.Fatalf("https server failed: %v", err)
}
}()
go func() {
<-ctx.Done()
socketServer.Shutdown(context.Background())
}()
<-ctx.Done()
return ctx.Err()
}
30 changes: 30 additions & 0 deletions internal/server/listener_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//go:build unix
// +build unix

package server

import (
"fmt"
"net"
"net/url"

"github.com/cnrancher/kube-explorer/internal/config"
)

func ensureListener() (net.Listener, string, error) {
if config.BindAddress == "" {
return nil, "", nil
}
u, err := url.Parse(config.BindAddress)
if err != nil {
return nil, "", err
}
if u.Scheme == "" || u.Scheme == "tcp" {
return nil, u.Host, nil
}
if u.Scheme != "unix" {
return nil, "", fmt.Errorf("Unsupported scheme %s, only tcp and unix are supported in UNIX OS", u.Scheme)
}
listener, err := net.Listen("unix", u.Path)
return listener, u.Path, err
}
31 changes: 31 additions & 0 deletions internal/server/listener_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build windows
// +build windows

package server

import (
"fmt"
"net"
"net/url"

"github.com/Microsoft/go-winio"
"github.com/cnrancher/kube-explorer/internal/config"
)

func ensureListener() (net.Listener, string, error) {
if config.BindAddress == "" {
return nil, "", nil
}
u, err := url.Parse(config.BindAddress)
if err != nil {
return nil, "", err
}
if u.Scheme == "" || u.Scheme == "tcp" {
return nil, u.Host, nil
}
if u.Scheme != "namedpipe" {
return nil, "", fmt.Errorf("Unsupported scheme %s, only tcp and namedpipe are supported in windows", u.Scheme)
}
listener, err := winio.ListenPipe(fmt.Sprintf("//%s/%s", u.Host, u.Path), nil)
return listener, u.Path, err
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func run(_ *cli.Context) error {
if err != nil {
return err
}
return s.ListenAndServe(ctx, keconfig.Steve.HTTPSListenPort, keconfig.Steve.HTTPListenPort, nil)
return server.Serve(ctx, s)
}

func joinFlags(flags ...[]cli.Flag) []cli.Flag {
Expand Down

0 comments on commit 04c38da

Please sign in to comment.