From 17e39b20f72ab9300357241345a41609e544d08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20B=C3=BClow?= Date: Thu, 26 Oct 2023 21:32:21 +0200 Subject: [PATCH] server is getting a web interface --- client/cmd/register.go | 56 +++++++++++++++++++++++++++++-- client/utils/handleError.go | 15 +++++++++ client/utils/hostname.go | 11 ++++++ server/api/endpoint/register.go | 2 +- server/web/router.go | 13 +++++++ server/web/static/static.go | 6 ++++ server/web/templates/templates.go | 6 ++++ 7 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 client/utils/handleError.go create mode 100644 client/utils/hostname.go create mode 100644 server/web/router.go create mode 100644 server/web/static/static.go create mode 100644 server/web/templates/templates.go diff --git a/client/cmd/register.go b/client/cmd/register.go index 3aa2418..c4456e7 100644 --- a/client/cmd/register.go +++ b/client/cmd/register.go @@ -4,12 +4,35 @@ Copyright © 2023 NAME HERE package cmd import ( + "bytes" + "encoding/json" "fmt" + "git.jmbit.de/jmb/patchman/client/utils" + "git.jmbit.de/jmb/patchman/common" + "github.com/google/uuid" "github.com/spf13/viper" + "io" + "log" + "net/http" + "os" "github.com/spf13/cobra" ) +var token string +var output string +var serverUrl string + +type Registration struct { + hostname string + token string + secret string +} + +type ApiResponse struct { + uuid uuid.UUID +} + // registerCmd represents the register command var registerCmd = &cobra.Command{ Use: "register", @@ -18,10 +41,39 @@ var registerCmd = &cobra.Command{ patchman register --output /path/to/config --server https://patchman.example.com:443 --token `, Run: func(cmd *cobra.Command, args []string) { + secret, err := common.RandomString(64) + + if err != nil { + fmt.Fprintln(os.Stderr, "could not generate secret, please provide it manually!") + secret = "CHANGEME" + } fmt.Println("registering with Patchman Server") - viper.SetDefault("server", cmd.Flag("server")) + viper.SetDefault("server", serverUrl) + viper.SetDefault("secret", secret) viper.SetConfigName("client.yaml") viper.SetConfigType("yaml") + registration := Registration{ + hostname: utils.GetHostname(), + token: token, + secret: secret, + } + jsondata, err := json.Marshal(registration) + utils.HandleErrorFatal(err, "Could not parse registration Data") + request, err := http.NewRequest("POST", fmt.Sprintf("%s/v0/endpoint/register", serverUrl), bytes.NewBuffer(jsondata)) + utils.HandleErrorFatal(err, "Could not generate registration request") + request.Header.Set("Content-Type", "application/json") + client := &http.Client{} + response, err := client.Do(request) + utils.HandleErrorFatal(err, "Error making registration request") + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + utils.HandleError(err, "Could not close reader") + } + }(response.Body) + if response.StatusCode != http.StatusCreated { + log.Printf("Request failed with response %s", response.Status) + } }, } @@ -38,7 +90,7 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: // registerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") - registerCmd.Flags().String("output", "/etc/patchman/client.yaml", "Config file to create") + registerCmd.Flags().StringVar(&output, "output", "/etc/patchman/client.yaml", "Config file to create") registerCmd.Flags().String("server", "", "URL to Patchman server") registerCmd.Flags().String("token", "", "Registration token from Patchman Server") } diff --git a/client/utils/handleError.go b/client/utils/handleError.go new file mode 100644 index 0000000..4f1fc07 --- /dev/null +++ b/client/utils/handleError.go @@ -0,0 +1,15 @@ +package utils + +import "log" + +func HandleError(err error, msg string) { + if err != nil { + log.Printf("%s: %v", msg, err) + } +} + +func HandleErrorFatal(err error, msg string) { + if err != nil { + log.Fatalf("%s: %v", msg, err) + } +} diff --git a/client/utils/hostname.go b/client/utils/hostname.go new file mode 100644 index 0000000..c38a161 --- /dev/null +++ b/client/utils/hostname.go @@ -0,0 +1,11 @@ +package utils + +import "os" + +func GetHostname() string { + hostname, err := os.Hostname() + if err != nil { + hostname = "localhost" + } + return hostname +} diff --git a/server/api/endpoint/register.go b/server/api/endpoint/register.go index 7f67b2c..dc2e9cb 100644 --- a/server/api/endpoint/register.go +++ b/server/api/endpoint/register.go @@ -49,6 +49,6 @@ func Register(c *gin.Context) { result = database.DB.First(&usedToken) utils.HandleError(result.Error, http.StatusBadRequest, "Could not create Endpoint DB entry", c) - c.JSON(http.StatusOK, gin.H{"uuid": newEndpoint.ID}) + c.JSON(http.StatusCreated, gin.H{"uuid": newEndpoint.ID}) } diff --git a/server/web/router.go b/server/web/router.go new file mode 100644 index 0000000..7d21e2f --- /dev/null +++ b/server/web/router.go @@ -0,0 +1,13 @@ +package web + +import ( + "git.jmbit.de/jmb/patchman/server/web/static" + "github.com/gin-gonic/gin" + "net/http" +) + +func GroupWeb(router *gin.Engine) *gin.Engine { + router.StaticFS("/static", http.FS(static.StaticFS)) + + return router +} diff --git a/server/web/static/static.go b/server/web/static/static.go new file mode 100644 index 0000000..cc166f4 --- /dev/null +++ b/server/web/static/static.go @@ -0,0 +1,6 @@ +package static + +import "embed" + +//go:embed * +var StaticFS embed.FS diff --git a/server/web/templates/templates.go b/server/web/templates/templates.go new file mode 100644 index 0000000..dca5992 --- /dev/null +++ b/server/web/templates/templates.go @@ -0,0 +1,6 @@ +package templates + +import "embed" + +//go:embed * +var TemplatesFS embed.FS