mirror of
https://github.com/cirruslabs/orchard.git
synced 2026-10-18 04:43:12 +02:00
Introduce "orchard {port-forward, vnc} worker WORKER_NAME" (#140)
* Fix potential NPE in Client.wsRequest()
* Introduce "orchard {port-forward, vnc} worker WORKER_NAME"
* portspec.go: simplify logic and respect [LOCAL_PORT]:REMOTE_PORT format
This commit is contained in:
@@ -98,6 +98,9 @@ func (controller *Controller) initAPI() *gin.Engine {
|
||||
v1.GET("/workers", func(c *gin.Context) {
|
||||
controller.listWorkers(c).Respond(c)
|
||||
})
|
||||
v1.GET("/workers/:name/port-forward", func(c *gin.Context) {
|
||||
controller.portForwardWorker(c).Respond(c)
|
||||
})
|
||||
v1.DELETE("/workers/:name", func(c *gin.Context) {
|
||||
controller.deleteWorker(c).Respond(c)
|
||||
})
|
||||
|
||||
@@ -47,23 +47,34 @@ func (controller *Controller) portForwardVM(ctx *gin.Context) responder.Responde
|
||||
return responderImpl
|
||||
}
|
||||
|
||||
// Commence port-forwarding
|
||||
return controller.portForward(ctx, vm.Worker, vm.UID, uint32(port))
|
||||
}
|
||||
|
||||
func (controller *Controller) portForward(
|
||||
ctx *gin.Context,
|
||||
workerName string,
|
||||
vmUID string,
|
||||
port uint32,
|
||||
) responder.Responder {
|
||||
// Request and wait for a connection with a worker
|
||||
session := uuid.New().String()
|
||||
boomerangConnCh, cancel := controller.proxy.Request(ctx, session)
|
||||
defer cancel()
|
||||
|
||||
// send request to worker to initiate port-forwarding connection back to us
|
||||
err = controller.workerNotifier.Notify(ctx, vm.Worker, &rpc.WatchInstruction{
|
||||
err := controller.workerNotifier.Notify(ctx, workerName, &rpc.WatchInstruction{
|
||||
Action: &rpc.WatchInstruction_PortForwardAction{
|
||||
PortForwardAction: &rpc.WatchInstruction_PortForward{
|
||||
Session: session,
|
||||
VmUid: vm.UID,
|
||||
VmPort: uint32(port),
|
||||
VmUid: vmUID,
|
||||
Port: port,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
controller.logger.Warnf("failed to request port-forwarding from the worker %s: %v", vm.Worker, err)
|
||||
controller.logger.Warnf("failed to request port-forwarding from the worker %s: %v",
|
||||
workerName, err)
|
||||
|
||||
return responder.Code(http.StatusServiceUnavailable)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
storepkg "github.com/cirruslabs/orchard/internal/controller/store"
|
||||
"github.com/cirruslabs/orchard/internal/responder"
|
||||
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (controller *Controller) portForwardWorker(ctx *gin.Context) responder.Responder {
|
||||
if responder := controller.authorize(ctx, v1.ServiceAccountRoleAdminWrite); responder != nil {
|
||||
return responder
|
||||
}
|
||||
|
||||
// Retrieve and parse path and query parameters
|
||||
name := ctx.Param("name")
|
||||
|
||||
portRaw := ctx.Query("port")
|
||||
port, err := strconv.ParseUint(portRaw, 10, 16)
|
||||
if err != nil {
|
||||
return responder.Code(http.StatusBadRequest)
|
||||
}
|
||||
if port < 1 || port > 65535 {
|
||||
return responder.Code(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
var worker *v1.Worker
|
||||
|
||||
if responder := controller.storeView(func(txn storepkg.Transaction) responder.Responder {
|
||||
worker, err = txn.GetWorker(name)
|
||||
if err != nil {
|
||||
return responder.Error(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); responder != nil {
|
||||
return responder
|
||||
}
|
||||
|
||||
// Commence port-forwarding
|
||||
return controller.portForward(ctx, worker.Name, "", uint32(port))
|
||||
}
|
||||
Reference in New Issue
Block a user