diff --git a/hscontrol/db/node.go b/hscontrol/db/node.go index 6aa75018..09bc795d 100644 --- a/hscontrol/db/node.go +++ b/hscontrol/db/node.go @@ -194,7 +194,8 @@ func (hsdb *HSDatabase) SetTags( }) } -// SetTags takes a Node struct pointer and update the forced tags. +// SetTags takes a NodeID and update the forced tags. +// It will overwrite any tags with the new list. func SetTags( tx *gorm.DB, nodeID types.NodeID, @@ -209,14 +210,9 @@ func SetTags( return nil } - var newTags []string - for _, tag := range tags { - if !slices.Contains(newTags, tag) { - newTags = append(newTags, tag) - } - } - - b, err := json.Marshal(newTags) + slices.Sort(tags) + tags = slices.Compact(tags) + b, err := json.Marshal(tags) if err != nil { return err } diff --git a/hscontrol/types/node.go b/hscontrol/types/node.go index 2e6a0eeb..3af43473 100644 --- a/hscontrol/types/node.go +++ b/hscontrol/types/node.go @@ -80,7 +80,11 @@ type Node struct { RegisterMethod string - ForcedTags []string `gorm:"serializer:json"` + // ForcedTags are tags set by CLI/API. It is not considered + // the source of truth, but is one of the sources from + // which a tag might originate. + // ForcedTags are _always_ applied to the node. + ForcedTags []string `gorm:"column:forced_tags;serializer:json"` // When a node has been created with a PreAuthKey, we need to // prevent the preauthkey from being deleted before the node. diff --git a/hscontrol/types/preauth_key.go b/hscontrol/types/preauth_key.go index 9c190c5c..7fa67366 100644 --- a/hscontrol/types/preauth_key.go +++ b/hscontrol/types/preauth_key.go @@ -16,9 +16,14 @@ type PreAuthKey struct { UserID uint User User `gorm:"constraint:OnDelete:SET NULL;"` Reusable bool - Ephemeral bool `gorm:"default:false"` - Used bool `gorm:"default:false"` - Tags []string `gorm:"serializer:json"` + Ephemeral bool `gorm:"default:false"` + Used bool `gorm:"default:false"` + + // Tags are always applied to the node and is one of + // the sources of tags a node might have. They are copied + // from the PreAuthKey when the node logs in the first time, + // and ignored after. + Tags []string `gorm:"serializer:json"` CreatedAt *time.Time Expiration *time.Time