From 306a80cf5727893fde366fa8954ee93c03d60d6b Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sat, 16 Oct 2021 11:14:37 -0400 Subject: [PATCH 1/2] Bugfix: when namespace destruction causes a database error, return the error, not nil. --- namespaces.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namespaces.go b/namespaces.go index e109b9a..4d996bb 100644 --- a/namespaces.go +++ b/namespaces.go @@ -59,7 +59,7 @@ func (h *Headscale) DestroyNamespace(name string) error { } if result := h.db.Unscoped().Delete(&n); result.Error != nil { - return err + return result.Error } return nil From 7dcf4a514700b9686d7756ceeed7396b6cec4a88 Mon Sep 17 00:00:00 2001 From: Ward Vandewege Date: Sat, 16 Oct 2021 11:20:06 -0400 Subject: [PATCH 2/2] Add support for renaming namespaces. --- cmd/headscale/cli/namespaces.go | 29 +++++++++++++++++++++++++++++ namespaces.go | 29 +++++++++++++++++++++++++++++ namespaces_test.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index c35c02c..4287037 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -15,6 +15,7 @@ func init() { namespaceCmd.AddCommand(createNamespaceCmd) namespaceCmd.AddCommand(listNamespacesCmd) namespaceCmd.AddCommand(destroyNamespaceCmd) + namespaceCmd.AddCommand(renameNamespaceCmd) } var namespaceCmd = &cobra.Command{ @@ -107,3 +108,31 @@ var listNamespacesCmd = &cobra.Command{ } }, } + +var renameNamespaceCmd = &cobra.Command{ + Use: "rename OLD_NAME NEW_NAME", + Short: "Renames a namespace", + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 2 { + return fmt.Errorf("Missing parameters") + } + return nil + }, + Run: func(cmd *cobra.Command, args []string) { + o, _ := cmd.Flags().GetString("output") + h, err := getHeadscaleApp() + if err != nil { + log.Fatalf("Error initializing: %s", err) + } + err = h.RenameNamespace(args[0], args[1]) + if strings.HasPrefix(o, "json") { + JsonOutput(map[string]string{"Result": "Namespace renamed"}, err, o) + return + } + if err != nil { + fmt.Printf("Error renaming namespace: %s\n", err) + return + } + fmt.Printf("Namespace renamed\n") + }, +} diff --git a/namespaces.go b/namespaces.go index 4d996bb..dc4096b 100644 --- a/namespaces.go +++ b/namespaces.go @@ -65,6 +65,35 @@ func (h *Headscale) DestroyNamespace(name string) error { return nil } +// RenameNamespace renames a Namespace. Returns error if the Namespace does +// not exist or if another Namespace exists with the new name. +func (h *Headscale) RenameNamespace(oldName, newName string) error { + n, err := h.GetNamespace(oldName) + if err != nil { + return err + } + _, err = h.GetNamespace(newName) + if err == nil { + return errorNamespaceExists + } + if !errors.Is(err, errorNamespaceNotFound) { + return err + } + + n.Name = newName + + if result := h.db.Save(&n); result.Error != nil { + return result.Error + } + + err = h.RequestMapUpdates(n.ID) + if err != nil { + return err + } + + return nil +} + // GetNamespace fetches a namespace by name func (h *Headscale) GetNamespace(name string) (*Namespace, error) { n := Namespace{} diff --git a/namespaces_test.go b/namespaces_test.go index 9168b20..92c868a 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -46,3 +46,32 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { err = h.DestroyNamespace("test") c.Assert(err, check.Equals, errorNamespaceNotEmpty) } + +func (s *Suite) TestRenameNamespace(c *check.C) { + n, err := h.CreateNamespace("test") + c.Assert(err, check.IsNil) + c.Assert(n.Name, check.Equals, "test") + + ns, err := h.ListNamespaces() + c.Assert(err, check.IsNil) + c.Assert(len(*ns), check.Equals, 1) + + err = h.RenameNamespace("test", "test_renamed") + c.Assert(err, check.IsNil) + + _, err = h.GetNamespace("test") + c.Assert(err, check.Equals, errorNamespaceNotFound) + + _, err = h.GetNamespace("test_renamed") + c.Assert(err, check.IsNil) + + err = h.RenameNamespace("test_does_not_exit", "test") + c.Assert(err, check.Equals, errorNamespaceNotFound) + + n2, err := h.CreateNamespace("test2") + c.Assert(err, check.IsNil) + c.Assert(n2.Name, check.Equals, "test2") + + err = h.RenameNamespace("test2", "test_renamed") + c.Assert(err, check.Equals, errorNamespaceExists) +}