2021-09-02 22:57:26 +08:00
|
|
|
package headscale
|
|
|
|
|
|
|
|
import "gorm.io/gorm"
|
|
|
|
|
2021-11-13 16:36:45 +08:00
|
|
|
const (
|
2021-11-16 00:33:16 +08:00
|
|
|
errSameNamespace = Error("Destination namespace same as origin")
|
|
|
|
errMachineAlreadyShared = Error("Node already shared to this namespace")
|
|
|
|
errMachineNotShared = Error("Machine not shared to this namespace")
|
2021-11-13 16:36:45 +08:00
|
|
|
)
|
2021-09-02 22:57:26 +08:00
|
|
|
|
2021-11-13 16:39:04 +08:00
|
|
|
// SharedMachine is a join table to support sharing nodes between namespaces.
|
2021-09-06 20:43:43 +08:00
|
|
|
type SharedMachine struct {
|
2021-09-02 22:57:26 +08:00
|
|
|
gorm.Model
|
|
|
|
MachineID uint64
|
|
|
|
Machine Machine
|
|
|
|
NamespaceID uint
|
|
|
|
Namespace Namespace
|
|
|
|
}
|
|
|
|
|
2021-11-13 16:39:04 +08:00
|
|
|
// AddSharedMachineToNamespace adds a machine as a shared node to a namespace.
|
2021-11-15 03:32:03 +08:00
|
|
|
func (h *Headscale) AddSharedMachineToNamespace(
|
|
|
|
machine *Machine,
|
|
|
|
namespace *Namespace,
|
|
|
|
) error {
|
|
|
|
if machine.NamespaceID == namespace.ID {
|
2021-11-16 00:33:16 +08:00
|
|
|
return errSameNamespace
|
2021-09-02 22:57:26 +08:00
|
|
|
}
|
|
|
|
|
2021-10-17 23:29:03 +08:00
|
|
|
sharedMachines := []SharedMachine{}
|
2021-11-15 03:32:03 +08:00
|
|
|
if err := h.db.Where("machine_id = ? AND namespace_id = ?", machine.ID, namespace.ID).Find(&sharedMachines).Error; err != nil {
|
2021-10-17 23:29:03 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if len(sharedMachines) > 0 {
|
2021-11-16 00:33:16 +08:00
|
|
|
return errMachineAlreadyShared
|
2021-09-02 22:57:26 +08:00
|
|
|
}
|
|
|
|
|
2021-10-17 23:29:03 +08:00
|
|
|
sharedMachine := SharedMachine{
|
2021-11-15 03:32:03 +08:00
|
|
|
MachineID: machine.ID,
|
|
|
|
Machine: *machine,
|
|
|
|
NamespaceID: namespace.ID,
|
|
|
|
Namespace: *namespace,
|
2021-09-02 22:57:26 +08:00
|
|
|
}
|
2021-09-10 06:26:46 +08:00
|
|
|
h.db.Save(&sharedMachine)
|
2021-09-02 22:57:26 +08:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2021-10-11 05:55:03 +08:00
|
|
|
|
2021-11-13 16:39:04 +08:00
|
|
|
// RemoveSharedMachineFromNamespace removes a shared machine from a namespace.
|
2021-11-15 03:32:03 +08:00
|
|
|
func (h *Headscale) RemoveSharedMachineFromNamespace(
|
|
|
|
machine *Machine,
|
|
|
|
namespace *Namespace,
|
|
|
|
) error {
|
|
|
|
if machine.NamespaceID == namespace.ID {
|
2021-10-25 05:00:51 +08:00
|
|
|
// Can't unshare from primary namespace
|
2021-11-16 00:33:16 +08:00
|
|
|
return errMachineNotShared
|
2021-10-18 04:29:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
sharedMachine := SharedMachine{}
|
2021-11-15 03:32:03 +08:00
|
|
|
result := h.db.Where("machine_id = ? AND namespace_id = ?", machine.ID, namespace.ID).
|
2021-11-13 16:36:45 +08:00
|
|
|
Unscoped().
|
|
|
|
Delete(&sharedMachine)
|
2021-10-18 04:29:30 +08:00
|
|
|
if result.Error != nil {
|
|
|
|
return result.Error
|
|
|
|
}
|
|
|
|
|
|
|
|
if result.RowsAffected == 0 {
|
2021-11-16 00:33:16 +08:00
|
|
|
return errMachineNotShared
|
2021-10-18 04:29:30 +08:00
|
|
|
}
|
|
|
|
|
2021-11-15 03:32:03 +08:00
|
|
|
err := h.RequestMapUpdates(namespace.ID)
|
2021-10-18 04:29:30 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-11-13 16:39:04 +08:00
|
|
|
// RemoveSharedMachineFromAllNamespaces removes a machine as a shared node from all namespaces.
|
2021-11-15 03:32:03 +08:00
|
|
|
func (h *Headscale) RemoveSharedMachineFromAllNamespaces(machine *Machine) error {
|
2021-10-11 05:55:03 +08:00
|
|
|
sharedMachine := SharedMachine{}
|
2021-11-15 03:32:03 +08:00
|
|
|
if result := h.db.Where("machine_id = ?", machine.ID).Unscoped().Delete(&sharedMachine); result.Error != nil {
|
2021-10-11 05:55:03 +08:00
|
|
|
return result.Error
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|