mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-29 18:33:05 +00:00
Remove Gin from simple endpoints for TS2019
This commit is contained in:
parent
3ae340527f
commit
367da0fcc2
4 changed files with 111 additions and 96 deletions
36
api.go
36
api.go
|
@ -32,12 +32,13 @@ const (
|
||||||
|
|
||||||
// KeyHandler provides the Headscale pub key
|
// KeyHandler provides the Headscale pub key
|
||||||
// Listens in /key.
|
// Listens in /key.
|
||||||
func (h *Headscale) KeyHandler(ctx *gin.Context) {
|
func (h *Headscale) KeyHandler(
|
||||||
ctx.Data(
|
w http.ResponseWriter,
|
||||||
http.StatusOK,
|
r *http.Request,
|
||||||
"text/plain; charset=utf-8",
|
) {
|
||||||
[]byte(MachinePublicKeyStripPrefix(h.privateKey.Public())),
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte(MachinePublicKeyStripPrefix(h.privateKey.Public())))
|
||||||
}
|
}
|
||||||
|
|
||||||
type registerWebAPITemplateConfig struct {
|
type registerWebAPITemplateConfig struct {
|
||||||
|
@ -63,10 +64,15 @@ var registerWebAPITemplate = template.Must(
|
||||||
|
|
||||||
// RegisterWebAPI shows a simple message in the browser to point to the CLI
|
// RegisterWebAPI shows a simple message in the browser to point to the CLI
|
||||||
// Listens in /register.
|
// Listens in /register.
|
||||||
func (h *Headscale) RegisterWebAPI(ctx *gin.Context) {
|
func (h *Headscale) RegisterWebAPI(
|
||||||
machineKeyStr := ctx.Query("key")
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
|
machineKeyStr := r.URL.Query().Get("key")
|
||||||
if machineKeyStr == "" {
|
if machineKeyStr == "" {
|
||||||
ctx.String(http.StatusBadRequest, "Wrong params")
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte("Wrong params"))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -79,14 +85,14 @@ func (h *Headscale) RegisterWebAPI(ctx *gin.Context) {
|
||||||
Str("func", "RegisterWebAPI").
|
Str("func", "RegisterWebAPI").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render register web API template")
|
Msg("Could not render register web API template")
|
||||||
ctx.Data(
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
http.StatusInternalServerError,
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
"text/html; charset=utf-8",
|
w.Write([]byte("Could not render register web API template"))
|
||||||
[]byte("Could not render register web API template"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(content.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegistrationHandler handles the actual registration process of a machine
|
// RegistrationHandler handles the actual registration process of a machine
|
||||||
|
|
16
app.go
16
app.go
|
@ -397,18 +397,18 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine {
|
||||||
"/health",
|
"/health",
|
||||||
func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) },
|
func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) },
|
||||||
)
|
)
|
||||||
router.GET("/key", h.KeyHandler)
|
router.GET("/key", gin.WrapF(h.KeyHandler))
|
||||||
router.GET("/register", h.RegisterWebAPI)
|
router.GET("/register", gin.WrapF(h.RegisterWebAPI))
|
||||||
router.POST("/machine/:id/map", h.PollNetMapHandler)
|
router.POST("/machine/:id/map", h.PollNetMapHandler)
|
||||||
router.POST("/machine/:id", h.RegistrationHandler)
|
router.POST("/machine/:id", h.RegistrationHandler)
|
||||||
router.GET("/oidc/register/:mkey", h.RegisterOIDC)
|
router.GET("/oidc/register/:mkey", h.RegisterOIDC)
|
||||||
router.GET("/oidc/callback", h.OIDCCallback)
|
router.GET("/oidc/callback", h.OIDCCallback)
|
||||||
router.GET("/apple", h.AppleConfigMessage)
|
router.GET("/apple", gin.WrapF(h.AppleConfigMessage))
|
||||||
router.GET("/apple/:platform", h.ApplePlatformConfig)
|
router.GET("/apple/:platform", gin.WrapF(h.ApplePlatformConfig))
|
||||||
router.GET("/windows", h.WindowsConfigMessage)
|
router.GET("/windows", gin.WrapF(h.WindowsConfigMessage))
|
||||||
router.GET("/windows/tailscale.reg", h.WindowsRegConfig)
|
router.GET("/windows/tailscale.reg", gin.WrapF(h.WindowsRegConfig))
|
||||||
router.GET("/swagger", SwaggerUI)
|
router.GET("/swagger", gin.WrapF(SwaggerUI))
|
||||||
router.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1)
|
router.GET("/swagger/v1/openapiv2.json", gin.WrapF(SwaggerAPIv1))
|
||||||
|
|
||||||
if h.cfg.DERP.ServerEnabled {
|
if h.cfg.DERP.ServerEnabled {
|
||||||
router.Any("/derp", h.DERPHandler)
|
router.Any("/derp", h.DERPHandler)
|
||||||
|
|
|
@ -6,13 +6,15 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
textTemplate "text/template"
|
textTemplate "text/template"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WindowsConfigMessage shows a simple message in the browser for how to configure the Windows Tailscale client.
|
// WindowsConfigMessage shows a simple message in the browser for how to configure the Windows Tailscale client.
|
||||||
func (h *Headscale) WindowsConfigMessage(ctx *gin.Context) {
|
func (h *Headscale) WindowsConfigMessage(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
winTemplate := template.Must(template.New("windows").Parse(`
|
winTemplate := template.Must(template.New("windows").Parse(`
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
|
@ -63,20 +65,24 @@ REG ADD "HKLM\Software\Tailscale IPN" /v LoginURL /t REG_SZ /d "{{.URL}}"</code>
|
||||||
Str("handler", "WindowsRegConfig").
|
Str("handler", "WindowsRegConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Windows index template")
|
Msg("Could not render Windows index template")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Windows index template"),
|
w.Write([]byte("Could not render Windows index template"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes())
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(payload.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// WindowsRegConfig generates and serves a .reg file configured with the Headscale server address.
|
// WindowsRegConfig generates and serves a .reg file configured with the Headscale server address.
|
||||||
func (h *Headscale) WindowsRegConfig(ctx *gin.Context) {
|
func (h *Headscale) WindowsRegConfig(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
config := WindowsRegistryConfig{
|
config := WindowsRegistryConfig{
|
||||||
URL: h.cfg.ServerURL,
|
URL: h.cfg.ServerURL,
|
||||||
}
|
}
|
||||||
|
@ -87,24 +93,24 @@ func (h *Headscale) WindowsRegConfig(ctx *gin.Context) {
|
||||||
Str("handler", "WindowsRegConfig").
|
Str("handler", "WindowsRegConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Apple macOS template")
|
Msg("Could not render Apple macOS template")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Windows registry template"),
|
w.Write([]byte("Could not render Windows registry template"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data(
|
w.Header().Set("Content-Type", "text/x-ms-regedit; charset=utf-8")
|
||||||
http.StatusOK,
|
w.WriteHeader(http.StatusOK)
|
||||||
"text/x-ms-regedit; charset=utf-8",
|
w.Write(content.Bytes())
|
||||||
content.Bytes(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppleConfigMessage shows a simple message in the browser to point the user to the iOS/MacOS profile and instructions for how to install it.
|
// AppleConfigMessage shows a simple message in the browser to point the user to the iOS/MacOS profile and instructions for how to install it.
|
||||||
func (h *Headscale) AppleConfigMessage(ctx *gin.Context) {
|
func (h *Headscale) AppleConfigMessage(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
appleTemplate := template.Must(template.New("apple").Parse(`
|
appleTemplate := template.Must(template.New("apple").Parse(`
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
|
@ -165,20 +171,24 @@ func (h *Headscale) AppleConfigMessage(ctx *gin.Context) {
|
||||||
Str("handler", "AppleMobileConfig").
|
Str("handler", "AppleMobileConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Apple index template")
|
Msg("Could not render Apple index template")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Apple index template"),
|
w.Write([]byte("Could not render Apple index template"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes())
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(payload.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
|
func (h *Headscale) ApplePlatformConfig(
|
||||||
platform := ctx.Param("platform")
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
|
platform := r.URL.Query().Get("platform")
|
||||||
|
|
||||||
id, err := uuid.NewV4()
|
id, err := uuid.NewV4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -186,11 +196,10 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
|
||||||
Str("handler", "ApplePlatformConfig").
|
Str("handler", "ApplePlatformConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Failed not create UUID")
|
Msg("Failed not create UUID")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Failed to create UUID"),
|
w.Write([]byte("Failed to create UUID"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -201,11 +210,10 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
|
||||||
Str("handler", "ApplePlatformConfig").
|
Str("handler", "ApplePlatformConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Failed not create UUID")
|
Msg("Failed not create UUID")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Failed to create UUID"),
|
w.Write([]byte("Failed to create content UUID"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -224,11 +232,10 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
|
||||||
Str("handler", "ApplePlatformConfig").
|
Str("handler", "ApplePlatformConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Apple macOS template")
|
Msg("Could not render Apple macOS template")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Apple macOS template"),
|
w.Write([]byte("Could not render Apple macOS template"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -238,20 +245,17 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
|
||||||
Str("handler", "ApplePlatformConfig").
|
Str("handler", "ApplePlatformConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Apple iOS template")
|
Msg("Could not render Apple iOS template")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Apple iOS template"),
|
w.Write([]byte("Could not render Apple iOS template"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ctx.Data(
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
http.StatusOK,
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
"text/html; charset=utf-8",
|
w.Write([]byte("Invalid platform, only ios and macos is supported"))
|
||||||
[]byte("Invalid platform, only ios and macos is supported"),
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -268,20 +272,17 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
|
||||||
Str("handler", "ApplePlatformConfig").
|
Str("handler", "ApplePlatformConfig").
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Apple platform template")
|
Msg("Could not render Apple platform template")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Apple platform template"),
|
w.Write([]byte("Could not render Apple platform template"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data(
|
w.Header().Set("Content-Type", "application/x-apple-aspen-config; charset=utf-8")
|
||||||
http.StatusOK,
|
w.WriteHeader(http.StatusOK)
|
||||||
"application/x-apple-aspen-config; charset=utf-8",
|
w.Write(content.Bytes())
|
||||||
content.Bytes(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WindowsRegistryConfig struct {
|
type WindowsRegistryConfig struct {
|
||||||
|
|
28
swagger.go
28
swagger.go
|
@ -6,14 +6,16 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed gen/openapiv2/headscale/v1/headscale.swagger.json
|
//go:embed gen/openapiv2/headscale/v1/headscale.swagger.json
|
||||||
var apiV1JSON []byte
|
var apiV1JSON []byte
|
||||||
|
|
||||||
func SwaggerUI(ctx *gin.Context) {
|
func SwaggerUI(
|
||||||
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
swaggerTemplate := template.Must(template.New("swagger").Parse(`
|
swaggerTemplate := template.Must(template.New("swagger").Parse(`
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -52,18 +54,24 @@ func SwaggerUI(ctx *gin.Context) {
|
||||||
Caller().
|
Caller().
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("Could not render Swagger")
|
Msg("Could not render Swagger")
|
||||||
ctx.Data(
|
|
||||||
http.StatusInternalServerError,
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
"text/html; charset=utf-8",
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
[]byte("Could not render Swagger"),
|
w.Write([]byte("Could not render Swagger"))
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes())
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(payload.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func SwaggerAPIv1(ctx *gin.Context) {
|
func SwaggerAPIv1(
|
||||||
ctx.Data(http.StatusOK, "application/json; charset=utf-8", apiV1JSON)
|
w http.ResponseWriter,
|
||||||
|
r *http.Request,
|
||||||
|
) {
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-88")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write(apiV1JSON)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue