Port forwarding support (#30)

* Port forwarding support

* .golangci.yml: remove and replace deprecated and archived linters

* Client: pass credentials when calling WebSocket API methods

* API: require ServiceAccountRoleComputeWrite role for port forwarding

* Use Buf

* Rename Poll() RPC method to Watch()

* Split Rendezvous into two parts: Watcher and Proxy (#32)

* Split Rendezvous into two parts: Watcher and Proxy

* Implement Proxy cancellation

* Use Protocol Buffers structure directly in Watcher

* Fix TestWatcher after switching to Protocol Buffers structure

* portForwardVM(): ensure we also check for gin's context
This commit is contained in:
Nikolay Edigaryev
2023-03-14 11:31:13 -04:00
committed by GitHub
parent 0582108ea6
commit 47fef47d1c
37 changed files with 2304 additions and 171 deletions
+36 -9
View File
@@ -5,21 +5,23 @@ import (
"crypto/tls"
"errors"
"fmt"
"github.com/cirruslabs/orchard/internal/controller/rendezvous"
storepkg "github.com/cirruslabs/orchard/internal/controller/store"
"github.com/cirruslabs/orchard/internal/controller/store/badger"
"github.com/cirruslabs/orchard/internal/netconstants"
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
"github.com/cirruslabs/orchard/rpc"
"github.com/google/uuid"
"go.uber.org/zap"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
"net"
"net/http"
"time"
)
const (
DefaultPort = 6120
DefaultServerName = "orchard-controller"
)
var (
ErrInitFailed = errors.New("controller initialization failed")
ErrAdminTaskFailed = errors.New("controller administrative task failed")
@@ -34,10 +36,18 @@ type Controller struct {
insecureAuthDisabled bool
store storepkg.Store
logger *zap.SugaredLogger
grpcServer *grpc.Server
watcher *rendezvous.Watcher
proxy *rendezvous.Proxy
rpc.UnimplementedControllerServer
}
func New(opts ...Option) (*Controller, error) {
controller := &Controller{}
controller := &Controller{
watcher: rendezvous.NewWatcher(),
proxy: rendezvous.NewProxy(),
}
// Apply options
for _, opt := range opts {
@@ -50,7 +60,7 @@ func New(opts ...Option) (*Controller, error) {
ErrInitFailed)
}
if controller.listenAddr == "" {
controller.listenAddr = fmt.Sprintf(":%d", DefaultPort)
controller.listenAddr = fmt.Sprintf(":%d", netconstants.DefaultControllerPort)
}
if controller.logger == nil {
controller.logger = zap.NewNop().Sugar()
@@ -73,9 +83,26 @@ func New(opts ...Option) (*Controller, error) {
controller.listener = listener
}
apiServer := controller.initAPI()
controller.grpcServer = grpc.NewServer(
grpc.KeepaliveParams(keepalive.ServerParameters{
Time: 30 * time.Second,
}),
)
rpc.RegisterControllerServer(controller.grpcServer, controller)
handler := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if request.Header.Get("Content-Type") == "application/grpc" {
controller.grpcServer.ServeHTTP(writer, request)
} else {
apiServer.ServeHTTP(writer, request)
}
})
controller.httpServer = &http.Server{
Handler: controller.initAPI(),
ReadTimeout: 5 * time.Second,
Handler: h2c.NewHandler(handler, &http2.Server{}),
ReadTimeout: 60 * time.Second,
}
return controller, nil