From 75b58d0784a5de752c19956292654023ff0ce49f Mon Sep 17 00:00:00 2001 From: Johan Siebens Date: Fri, 29 Dec 2023 14:47:11 +0100 Subject: [PATCH] feat: add query feature endpoint for 'serve' support --- internal/handlers/query_feature.go | 70 ++++++++++++++++++++++++++++++ internal/server/server.go | 2 + 2 files changed, 72 insertions(+) create mode 100644 internal/handlers/query_feature.go diff --git a/internal/handlers/query_feature.go b/internal/handlers/query_feature.go new file mode 100644 index 00000000..46265875 --- /dev/null +++ b/internal/handlers/query_feature.go @@ -0,0 +1,70 @@ +package handlers + +import ( + "fmt" + "github.com/jsiebens/ionscale/internal/bind" + "github.com/jsiebens/ionscale/internal/dns" + "github.com/jsiebens/ionscale/internal/domain" + "github.com/labstack/echo/v4" + "net/http" + "tailscale.com/tailcfg" +) + +func NewQueryFeatureHandlers(createBinder bind.Factory, dnsProvider dns.Provider, repository domain.Repository) *QueryFeatureHandlers { + return &QueryFeatureHandlers{ + createBinder: createBinder, + repository: repository, + } +} + +type QueryFeatureHandlers struct { + createBinder bind.Factory + dnsProvider dns.Provider + repository domain.Repository +} + +func (h *QueryFeatureHandlers) QueryFeature(c echo.Context) error { + ctx := c.Request().Context() + + binder, err := h.createBinder(c) + if err != nil { + return logError(err) + } + + req := new(tailcfg.QueryFeatureRequest) + if err := binder.BindRequest(c, req); err != nil { + return logError(err) + } + + machineKey := binder.Peer().String() + nodeKey := req.NodeKey.String() + + resp := tailcfg.QueryFeatureResponse{} + + switch req.Feature { + case "serve": + machine, err := h.repository.GetMachineByKeys(ctx, machineKey, nodeKey) + if err != nil { + return err + } + + if machine == nil { + return echo.NewHTTPError(http.StatusBadRequest) + } + + if h.dnsProvider == nil || machine.Tailnet.DNSConfig.HttpsCertsEnabled { + resp.Text = fmt.Sprintf(serverMessage, machine.Tailnet.Name) + } + case "funnel": + resp.Text = fmt.Sprintf("Sorry, ionscale has no support for feature '%s'\n", req.Feature) + default: + resp.Text = fmt.Sprintf("Unknown feature request '%s'\n", req.Feature) + } + + return binder.WriteResponse(c, http.StatusOK, resp) +} + +const serverMessage = `Enabling HTTPS is required to use Serve: + + ionscale tailnets set-dns --tailnet %s --https-certs=true --magic-dns +` diff --git a/internal/server/server.go b/internal/server/server.go index a230160d..82b8be0b 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -114,6 +114,7 @@ func Start(c *config.Config) error { dnsHandlers := handlers.NewDNSHandlers(binder, dnsProvider) idTokenHandlers := handlers.NewIDTokenHandlers(binder, c, repository) sshActionHandlers := handlers.NewSSHActionHandlers(binder, c, repository) + queryFeatureHandlers := handlers.NewQueryFeatureHandlers(binder, dnsProvider, repository) e := echo.New() e.Use(EchoMetrics(p), EchoLogger(httpLogger), EchoErrorHandler(), EchoRecover()) @@ -124,6 +125,7 @@ func Start(c *config.Config) error { e.GET("/machine/ssh/action/:src_machine_id/to/:dst_machine_id", sshActionHandlers.StartAuth) e.GET("/machine/ssh/action/:src_machine_id/to/:dst_machine_id/:check_period", sshActionHandlers.StartAuth) e.GET("/machine/ssh/action/check/:key", sshActionHandlers.CheckAuth) + e.POST("/machine/feature/query", queryFeatureHandlers.QueryFeature) return e }