diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index fe656a0c..ec02ea16 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -5,7 +5,9 @@ import ( "io" "log" "os" + "time" + "github.com/hako/durafmt" "github.com/juanfont/headscale" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -195,7 +197,7 @@ var listPreAuthKeys = &cobra.Command{ } for _, k := range *keys { fmt.Printf( - "key: %s, namespace: %s, reusable: %v, expiration: %s, created_at: %s", + "key: %s, namespace: %s, reusable: %v, expiration: %s, created_at: %s\n", k.Key, k.Namespace.Name, k.Reusable, @@ -206,6 +208,42 @@ var listPreAuthKeys = &cobra.Command{ }, } +var createPreAuthKeyCmd = &cobra.Command{ + Use: "create NAMESPACE", + Short: "Creates a new preauthkey in the specified namespace", + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("Missing parameters") + } + return nil + }, + Run: func(cmd *cobra.Command, args []string) { + h, err := getHeadscaleApp() + if err != nil { + log.Fatalf("Error initializing: %s", err) + } + reusable, _ := cmd.Flags().GetBool("reusable") + + e, _ := cmd.Flags().GetString("expiration") + var expiration *time.Time + if e != "" { + duration, err := durafmt.ParseStringShort(e) + if err != nil { + log.Fatalf("Error parsing expiration: %s", err) + } + exp := time.Now().UTC().Add(duration.Duration()) + expiration = &exp + } + + _, err = h.CreatePreAuthKey(args[0], reusable, expiration) + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("Ook.\n") + }, +} + func main() { viper.SetConfigName("config") viper.AddConfigPath("/etc/headscale/") @@ -231,6 +269,9 @@ func main() { nodeCmd.AddCommand(enableRouteCmd) preauthkeysCmd.AddCommand(listPreAuthKeys) + preauthkeysCmd.AddCommand(createPreAuthKeyCmd) + createPreAuthKeyCmd.PersistentFlags().Bool("reusable", false, "Make the preauthkey reusable") + createPreAuthKeyCmd.Flags().StringP("expiration", "e", "", "Human-readable expiration of the key (30m, 24h, 365d...)") if err := headscaleCmd.Execute(); err != nil { fmt.Println(err) diff --git a/go.mod b/go.mod index 8ac37bb2..b20125d1 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.16 require ( github.com/davecgh/go-spew v1.1.1 github.com/gin-gonic/gin v1.6.3 + github.com/hako/durafmt v0.0.0-20210316092057-3a2c319c1acd // indirect github.com/jinzhu/gorm v1.9.16 github.com/klauspost/compress v1.11.12 github.com/spf13/cobra v1.1.3 diff --git a/go.sum b/go.sum index a5ec5710..6dba504d 100644 --- a/go.sum +++ b/go.sum @@ -207,6 +207,8 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hako/durafmt v0.0.0-20210316092057-3a2c319c1acd h1:FsX+T6wA8spPe4c1K9vi7T0LvNCO1TTqiL8u7Wok2hw= +github.com/hako/durafmt v0.0.0-20210316092057-3a2c319c1acd/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=