mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Merge branch 'main' into docker-distroless
This commit is contained in:
		
						commit
						2f8e9f272c
					
				@ -3,6 +3,7 @@ package cli
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	survey "github.com/AlecAivazis/survey/v2"
 | 
			
		||||
	v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
 | 
			
		||||
	"github.com/pterm/pterm"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
@ -70,19 +71,44 @@ var destroyNamespaceCmd = &cobra.Command{
 | 
			
		||||
 | 
			
		||||
		namespaceName := args[0]
 | 
			
		||||
 | 
			
		||||
		request := &v1.GetNamespaceRequest{
 | 
			
		||||
			Name: namespaceName,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ctx, client, conn, cancel := getHeadscaleCLIClient()
 | 
			
		||||
		defer cancel()
 | 
			
		||||
		defer conn.Close()
 | 
			
		||||
 | 
			
		||||
		request := &v1.DeleteNamespaceRequest{Name: namespaceName}
 | 
			
		||||
 | 
			
		||||
		response, err := client.DeleteNamespace(ctx, request)
 | 
			
		||||
		_, err := client.GetNamespace(ctx, request)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output)
 | 
			
		||||
			ErrorOutput(err, fmt.Sprintf("Error: %s", status.Convert(err).Message()), output)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		SuccessOutput(response, "Namespace destroyed", output)
 | 
			
		||||
		confirm := false
 | 
			
		||||
		force, _ := cmd.Flags().GetBool("force")
 | 
			
		||||
		if !force {
 | 
			
		||||
			prompt := &survey.Confirm{
 | 
			
		||||
				Message: fmt.Sprintf("Do you want to remove the namespace '%s' and any associated preauthkeys?", namespaceName),
 | 
			
		||||
			}
 | 
			
		||||
			err := survey.AskOne(prompt, &confirm)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if confirm || force {
 | 
			
		||||
			request := &v1.DeleteNamespaceRequest{Name: namespaceName}
 | 
			
		||||
 | 
			
		||||
			response, err := client.DeleteNamespace(ctx, request)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			SuccessOutput(response, "Namespace destroyed", output)
 | 
			
		||||
		} else {
 | 
			
		||||
			SuccessOutput(map[string]string{"Result": "Namespace not destroyed"}, "Namespace not destroyed", output)
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,9 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	errorNamespaceExists   = Error("Namespace already exists")
 | 
			
		||||
	errorNamespaceNotFound = Error("Namespace not found")
 | 
			
		||||
	errorNamespaceNotEmpty = Error("Namespace not empty")
 | 
			
		||||
	errorNamespaceExists          = Error("Namespace already exists")
 | 
			
		||||
	errorNamespaceNotFound        = Error("Namespace not found")
 | 
			
		||||
	errorNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Namespace is the way Headscale implements the concept of users in Tailscale
 | 
			
		||||
@ -60,7 +60,18 @@ func (h *Headscale) DestroyNamespace(name string) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(m) > 0 {
 | 
			
		||||
		return errorNamespaceNotEmpty
 | 
			
		||||
		return errorNamespaceNotEmptyOfNodes
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	keys, err := h.ListPreAuthKeys(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for _, p := range keys {
 | 
			
		||||
		err = h.DestroyPreAuthKey(&p)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if result := h.db.Unscoped().Delete(&n); result.Error != nil {
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ package headscale
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	"gopkg.in/check.v1"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) {
 | 
			
		||||
@ -31,6 +32,19 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) {
 | 
			
		||||
	pak, err := h.CreatePreAuthKey(n.Name, false, false, nil)
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	err = h.DestroyNamespace("test")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	result := h.db.Preload("Namespace").First(&pak, "key = ?", pak.Key)
 | 
			
		||||
	// destroying a namespace also deletes all associated preauthkeys
 | 
			
		||||
	c.Assert(result.Error, check.Equals, gorm.ErrRecordNotFound)
 | 
			
		||||
 | 
			
		||||
	n, err = h.CreateNamespace("test")
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	pak, err = h.CreatePreAuthKey(n.Name, false, false, nil)
 | 
			
		||||
	c.Assert(err, check.IsNil)
 | 
			
		||||
 | 
			
		||||
	m := Machine{
 | 
			
		||||
		ID:             0,
 | 
			
		||||
		MachineKey:     "foo",
 | 
			
		||||
@ -45,7 +59,7 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) {
 | 
			
		||||
	h.db.Save(&m)
 | 
			
		||||
 | 
			
		||||
	err = h.DestroyNamespace("test")
 | 
			
		||||
	c.Assert(err, check.Equals, errorNamespaceNotEmpty)
 | 
			
		||||
	c.Assert(err, check.Equals, errorNamespaceNotEmptyOfNodes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Suite) TestRenameNamespace(c *check.C) {
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,16 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er
 | 
			
		||||
	return pak, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DestroyPreAuthKey destroys a preauthkey. Returns error if the PreAuthKey
 | 
			
		||||
// does not exist.
 | 
			
		||||
func (h *Headscale) DestroyPreAuthKey(pak *PreAuthKey) error {
 | 
			
		||||
	if result := h.db.Unscoped().Delete(&pak); result.Error != nil {
 | 
			
		||||
		return result.Error
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkExpirePreAuthKey marks a PreAuthKey as expired
 | 
			
		||||
func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error {
 | 
			
		||||
	if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user