mirror of
https://github.com/juanfont/headscale.git
synced 2025-06-05 01:20:21 +02:00
types/node: make user pointer
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
d3005b1d4f
commit
19add15927
@ -17,6 +17,7 @@ import (
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/must"
|
||||
)
|
||||
|
||||
@ -144,13 +145,15 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0:ab12:4843:2222:6273:2221"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0:ab12:4843:2222:6273:2222"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{},
|
||||
@ -191,7 +194,8 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.33.0.0/16"),
|
||||
@ -202,7 +206,8 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
@ -281,19 +286,22 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
// "internal" exit node
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tsaddr.ExitRoutes(),
|
||||
},
|
||||
@ -342,7 +350,8 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tsaddr.ExitRoutes(),
|
||||
},
|
||||
@ -351,12 +360,14 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
@ -449,7 +460,8 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tsaddr.ExitRoutes(),
|
||||
},
|
||||
@ -458,12 +470,14 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
@ -559,7 +573,8 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("8.0.0.0/16"), netip.MustParsePrefix("16.0.0.0/16")},
|
||||
},
|
||||
@ -568,12 +583,14 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
@ -647,7 +664,8 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("8.0.0.0/8"), netip.MustParsePrefix("16.0.0.0/8")},
|
||||
},
|
||||
@ -656,12 +674,14 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
@ -727,17 +747,19 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("172.16.0.0/24")},
|
||||
},
|
||||
ForcedTags: []string{"tag:access-servers"},
|
||||
Tags: []string{"tag:access-servers"},
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
@ -793,13 +815,15 @@ func TestReduceFilterRules(t *testing.T) {
|
||||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: users[3],
|
||||
User: &users[3],
|
||||
UserID: &users[3].ID,
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{p("172.16.0.0/24"), p("10.10.11.0/24"), p("10.10.12.0/24")},
|
||||
},
|
||||
@ -848,17 +872,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{
|
||||
@ -872,19 +899,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -895,17 +925,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -919,14 +952,16 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -937,17 +972,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -961,14 +999,16 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -979,17 +1019,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -1003,14 +1046,16 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1021,17 +1066,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -1045,19 +1093,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1068,17 +1119,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -1092,19 +1146,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1115,17 +1172,20 @@ func TestReduceNodes(t *testing.T) {
|
||||
&types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "joe"},
|
||||
User: &types.User{Name: "joe", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: types.User{Name: "mickael"},
|
||||
User: &types.User{Name: "mickael", Model: gorm.Model{ID: 3}},
|
||||
UserID: ptr.To(uint(3)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -1133,7 +1193,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
node: &types.Node{ // current nodes
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "marc"},
|
||||
User: &types.User{Name: "marc", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: nil,
|
||||
@ -1151,28 +1212,32 @@ func TestReduceNodes(t *testing.T) {
|
||||
Hostname: "ts-head-upcrmb",
|
||||
IPv4: ap("100.64.0.3"),
|
||||
IPv6: ap("fd7a:115c:a1e0::3"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
Hostname: "ts-unstable-rlwpvr",
|
||||
IPv4: ap("100.64.0.4"),
|
||||
IPv6: ap("fd7a:115c:a1e0::4"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 3,
|
||||
Hostname: "ts-head-8w6paa",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 4,
|
||||
Hostname: "ts-unstable-lys2ib",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{ // list of all ACLRules registered
|
||||
@ -1194,7 +1259,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
Hostname: "ts-head-8w6paa",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: types.Nodes{
|
||||
@ -1203,14 +1269,16 @@ func TestReduceNodes(t *testing.T) {
|
||||
Hostname: "ts-head-upcrmb",
|
||||
IPv4: ap("100.64.0.3"),
|
||||
IPv6: ap("fd7a:115c:a1e0::3"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
&types.Node{
|
||||
ID: 2,
|
||||
Hostname: "ts-unstable-rlwpvr",
|
||||
IPv4: ap("100.64.0.4"),
|
||||
IPv6: ap("fd7a:115c:a1e0::4"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1222,13 +1290,15 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "peer1",
|
||||
User: types.User{Name: "mini"},
|
||||
User: &types.User{Name: "mini", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
Hostname: "peer2",
|
||||
User: types.User{Name: "peer2"},
|
||||
User: &types.User{Name: "peer2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{
|
||||
@ -1244,7 +1314,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 0,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "mini",
|
||||
User: types.User{Name: "mini"},
|
||||
User: &types.User{Name: "mini", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
want: []*types.Node{
|
||||
@ -1252,7 +1323,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
Hostname: "peer2",
|
||||
User: types.User{Name: "peer2"},
|
||||
User: &types.User{Name: "peer2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1264,19 +1336,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "user1-2",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 0,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "user1-1",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.4"),
|
||||
Hostname: "user2-2",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{
|
||||
@ -1313,7 +1388,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
Hostname: "user-2-1",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: []*types.Node{
|
||||
@ -1321,19 +1397,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "user1-2",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 0,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "user1-1",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.4"),
|
||||
Hostname: "user2-2",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1345,19 +1424,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "user1-2",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
Hostname: "user-2-1",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.4"),
|
||||
Hostname: "user2-2",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{
|
||||
@ -1394,7 +1476,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 0,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "user1-1",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
want: []*types.Node{
|
||||
@ -1402,19 +1485,22 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "user1-2",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.3"),
|
||||
Hostname: "user-2-1",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
IPv4: ap("100.64.0.4"),
|
||||
Hostname: "user2-2",
|
||||
User: types.User{Name: "user2"},
|
||||
User: &types.User{Name: "user2", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1426,13 +1512,15 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "user1",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "router",
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.33.0.0/16")},
|
||||
},
|
||||
@ -1453,7 +1541,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "user1",
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
},
|
||||
want: []*types.Node{
|
||||
@ -1461,7 +1550,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "router",
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.33.0.0/16")},
|
||||
},
|
||||
@ -1477,7 +1567,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "router",
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")},
|
||||
},
|
||||
@ -1487,7 +1578,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "node",
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{
|
||||
@ -1504,7 +1596,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "router",
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")},
|
||||
},
|
||||
@ -1516,7 +1609,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "node",
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1528,7 +1622,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "router",
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")},
|
||||
},
|
||||
@ -1538,7 +1633,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "node",
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
rules: []tailcfg.FilterRule{
|
||||
@ -1555,7 +1651,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
Hostname: "node",
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
},
|
||||
want: []*types.Node{
|
||||
@ -1563,7 +1660,8 @@ func TestReduceNodes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
Hostname: "router",
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")},
|
||||
},
|
||||
@ -1599,28 +1697,28 @@ func TestSSHPolicyRules(t *testing.T) {
|
||||
nodeUser1 := types.Node{
|
||||
Hostname: "user1-device",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
UserID: 1,
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: ptr.To(users[0].ID),
|
||||
}
|
||||
nodeUser2 := types.Node{
|
||||
Hostname: "user2-device",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
UserID: 2,
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: ptr.To(users[1].ID),
|
||||
}
|
||||
taggedServer := types.Node{
|
||||
Hostname: "tagged-server",
|
||||
IPv4: ap("100.64.0.3"),
|
||||
UserID: 3,
|
||||
User: users[2],
|
||||
ForcedTags: []string{"tag:server"},
|
||||
User: &users[2],
|
||||
UserID: ptr.To(users[2].ID),
|
||||
Tags: []string{"tag:server"},
|
||||
}
|
||||
taggedClient := types.Node{
|
||||
Hostname: "tagged-client",
|
||||
IPv4: ap("100.64.0.4"),
|
||||
UserID: 2,
|
||||
User: users[1],
|
||||
ForcedTags: []string{"tag:client"},
|
||||
User: &users[1],
|
||||
UserID: ptr.To(users[1].ID),
|
||||
Tags: []string{"tag:client"},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@ -1986,7 +2084,8 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.0/24"),
|
||||
@ -2014,7 +2113,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.0/24"),
|
||||
@ -2040,7 +2139,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.0/24"),
|
||||
@ -2068,7 +2167,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.0/24"),
|
||||
@ -2095,7 +2194,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.0/24"),
|
||||
@ -2120,7 +2219,8 @@ func TestReduceRoutes(t *testing.T) {
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: types.User{Name: "user1"},
|
||||
User: &types.User{Name: "user1", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.0/24"),
|
||||
@ -2153,7 +2253,8 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"), // Node IP
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2185,7 +2286,8 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2212,7 +2314,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2240,7 +2342,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2278,7 +2380,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"), // node with IP 100.64.0.2
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2313,7 +2415,8 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 1,
|
||||
IPv4: ap("100.64.0.1"), // router with IP 100.64.0.1
|
||||
User: types.User{Name: "router"},
|
||||
User: &types.User{Name: "router", Model: gorm.Model{ID: 1}},
|
||||
UserID: ptr.To(uint(1)),
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2355,7 +2458,8 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"), // node
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node", Model: gorm.Model{ID: 2}},
|
||||
UserID: ptr.To(uint(2)),
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
@ -2389,7 +2493,7 @@ func TestReduceRoutes(t *testing.T) {
|
||||
node: &types.Node{
|
||||
ID: 2,
|
||||
IPv4: ap("100.64.0.2"), // node
|
||||
User: types.User{Name: "node"},
|
||||
User: &types.User{Name: "node"},
|
||||
},
|
||||
routes: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.10.10.0/24"),
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestNodeCanApproveRoute(t *testing.T) {
|
||||
@ -24,34 +25,34 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
||||
ID: 1,
|
||||
Hostname: "user1-device",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
UserID: 1,
|
||||
User: users[0],
|
||||
UserID: ptr.To(uint(1)),
|
||||
User: &users[0],
|
||||
}
|
||||
|
||||
exitNode := types.Node{
|
||||
ID: 2,
|
||||
Hostname: "user2-device",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
UserID: 2,
|
||||
User: users[1],
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: &users[1],
|
||||
}
|
||||
|
||||
taggedNode := types.Node{
|
||||
ID: 3,
|
||||
Hostname: "tagged-server",
|
||||
IPv4: ap("100.64.0.3"),
|
||||
UserID: 3,
|
||||
User: users[2],
|
||||
ForcedTags: []string{"tag:router"},
|
||||
UserID: ptr.To(uint(3)),
|
||||
User: &users[2],
|
||||
Tags: []string{"tag:router"},
|
||||
}
|
||||
|
||||
multiTagNode := types.Node{
|
||||
ID: 4,
|
||||
Hostname: "multi-tag-node",
|
||||
IPv4: ap("100.64.0.4"),
|
||||
UserID: 2,
|
||||
User: users[1],
|
||||
ForcedTags: []string{"tag:router", "tag:server"},
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: &users[1],
|
||||
Tags: []string{"tag:router", "tag:server"},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -359,7 +359,8 @@ func TestParsing(t *testing.T) {
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("200.200.200.200"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
Hostinfo: &tailcfg.Hostinfo{},
|
||||
},
|
||||
})
|
||||
|
@ -1,9 +1,10 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"github.com/juanfont/headscale/hscontrol/policy/matcher"
|
||||
"testing"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol/policy/matcher"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/juanfont/headscale/hscontrol/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -17,8 +18,8 @@ func node(name, ipv4, ipv6 string, user types.User, hostinfo *tailcfg.Hostinfo)
|
||||
Hostname: name,
|
||||
IPv4: ap(ipv4),
|
||||
IPv6: ap(ipv6),
|
||||
User: user,
|
||||
UserID: user.ID,
|
||||
User: &user,
|
||||
UserID: &user.ID,
|
||||
Hostinfo: hostinfo,
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ func (u Username) Resolve(_ *Policy, users types.Users, nodes types.Nodes) (*net
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
if node.IsTagged() {
|
||||
if !node.IsUserOwned() {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -515,7 +515,7 @@ func (ag AutoGroup) Resolve(p *Policy, users types.Users, nodes types.Nodes) (*n
|
||||
|
||||
for _, node := range nodes {
|
||||
// Skip if node has forced tags
|
||||
if len(node.ForcedTags) != 0 {
|
||||
if len(node.Tags) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -548,7 +548,7 @@ func (ag AutoGroup) Resolve(p *Policy, users types.Users, nodes types.Nodes) (*n
|
||||
|
||||
for _, node := range nodes {
|
||||
// Include if node has forced tags
|
||||
if len(node.ForcedTags) != 0 {
|
||||
if len(node.Tags) != 0 {
|
||||
node.AppendToIPSet(&build)
|
||||
continue
|
||||
}
|
||||
|
@ -6,12 +6,13 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/juanfont/headscale/hscontrol/types"
|
||||
"github.com/juanfont/headscale/hscontrol/util"
|
||||
"github.com/prometheus/common/model"
|
||||
"time"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go4.org/netipx"
|
||||
@ -1064,33 +1065,40 @@ func TestResolvePolicy(t *testing.T) {
|
||||
nodes: types.Nodes{
|
||||
// Not matching other user
|
||||
{
|
||||
User: users["notme"],
|
||||
User: ptr.To(users["notme"]),
|
||||
UserID: ptr.To(users["notme"].ID),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
// Not matching tags, usernames are ignored if a node is tagged
|
||||
{
|
||||
User: users["testuser"],
|
||||
ForcedTags: []string{"tag:anything"},
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Tags: []string{"tag:anything"},
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
// not matchin pak tag
|
||||
// since 0.27.0, tags are only considered when
|
||||
// set directly on the node, not via pak.
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
AuthKey: &types.PreAuthKey{
|
||||
Tags: []string{"alsotagged"},
|
||||
},
|
||||
IPv4: ap("100.100.101.3"),
|
||||
},
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
IPv4: ap("100.100.101.103"),
|
||||
},
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
IPv4: ap("100.100.101.104"),
|
||||
},
|
||||
},
|
||||
want: []netip.Prefix{mp("100.100.101.103/32"), mp("100.100.101.104/32")},
|
||||
want: []netip.Prefix{mp("100.100.101.3/32"), mp("100.100.101.103/32"), mp("100.100.101.104/32")},
|
||||
},
|
||||
{
|
||||
name: "group",
|
||||
@ -1098,29 +1106,45 @@ func TestResolvePolicy(t *testing.T) {
|
||||
nodes: types.Nodes{
|
||||
// Not matching other user
|
||||
{
|
||||
User: users["notme"],
|
||||
User: ptr.To(users["notme"]),
|
||||
UserID: ptr.To(users["notme"].ID),
|
||||
IPv4: ap("100.100.101.4"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
{
|
||||
User: users["groupuser"],
|
||||
ForcedTags: []string{"tag:anything"},
|
||||
User: ptr.To(users["groupuser"]),
|
||||
UserID: ptr.To(users["groupuser"].ID),
|
||||
Tags: []string{"tag:anything"},
|
||||
IPv4: ap("100.100.101.5"),
|
||||
},
|
||||
// not matchin pak tag
|
||||
// since 0.27.0, tags are only considered when
|
||||
// set directly on the node, not via pak.
|
||||
{
|
||||
User: users["groupuser"],
|
||||
User: ptr.To(users["groupuser"]),
|
||||
UserID: ptr.To(users["groupuser"].ID),
|
||||
AuthKey: &types.PreAuthKey{
|
||||
Tags: []string{"tag:alsotagged"},
|
||||
},
|
||||
IPv4: ap("100.100.101.6"),
|
||||
},
|
||||
{
|
||||
User: users["groupuser"],
|
||||
User: ptr.To(users["groupuser"]),
|
||||
UserID: ptr.To(users["groupuser"].ID),
|
||||
IPv4: ap("100.100.101.203"),
|
||||
},
|
||||
// not matchin username because tagged
|
||||
// since 0.27.0, tags are only considered when
|
||||
// set directly on the node, not via pak.
|
||||
{
|
||||
User: users["groupuser"],
|
||||
User: ptr.To(users["groupuser"]),
|
||||
UserID: ptr.To(users["groupuser"].ID),
|
||||
Tags: []string{"tag:taggg"},
|
||||
IPv4: ap("100.100.101.209"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(users["groupuser1"]),
|
||||
UserID: ptr.To(users["groupuser1"].ID),
|
||||
IPv4: ap("100.100.101.204"),
|
||||
},
|
||||
},
|
||||
@ -1130,7 +1154,7 @@ func TestResolvePolicy(t *testing.T) {
|
||||
"group:othergroup": Usernames{"notmetoo"},
|
||||
},
|
||||
},
|
||||
want: []netip.Prefix{mp("100.100.101.203/32"), mp("100.100.101.204/32")},
|
||||
want: []netip.Prefix{mp("100.100.101.6/32"), mp("100.100.101.203/32")},
|
||||
},
|
||||
{
|
||||
name: "tag",
|
||||
@ -1138,12 +1162,13 @@ func TestResolvePolicy(t *testing.T) {
|
||||
nodes: types.Nodes{
|
||||
// Not matching other user
|
||||
{
|
||||
User: users["notme"],
|
||||
User: ptr.To(users["notme"]),
|
||||
UserID: ptr.To(users["notme"].ID),
|
||||
IPv4: ap("100.100.101.9"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
{
|
||||
ForcedTags: []string{"tag:anything"},
|
||||
Tags: []string{"tag:anything"},
|
||||
IPv4: ap("100.100.101.10"),
|
||||
},
|
||||
// not matchin pak tag
|
||||
@ -1153,12 +1178,21 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
IPv4: ap("100.100.101.11"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
// matching forced tags
|
||||
{
|
||||
ForcedTags: []string{"tag:test"},
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.234"),
|
||||
},
|
||||
// matching tag with user (user is ignored)
|
||||
{
|
||||
User: ptr.To(users["notme"]),
|
||||
UserID: ptr.To(users["notme"].ID),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.109"),
|
||||
},
|
||||
// not matchin pak tag
|
||||
// since 0.27.0, tags are only considered when
|
||||
// set directly on the node, not via pak.
|
||||
{
|
||||
AuthKey: &types.PreAuthKey{
|
||||
Tags: []string{"tag:test"},
|
||||
@ -1168,7 +1202,7 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// TODO(kradalby): tests handling TagOwners + hostinfo
|
||||
pol: &Policy{},
|
||||
want: []netip.Prefix{mp("100.100.101.234/32"), mp("100.100.101.239/32")},
|
||||
want: []netip.Prefix{mp("100.100.101.109/32"), mp("100.100.101.234/32")},
|
||||
},
|
||||
{
|
||||
name: "empty-policy",
|
||||
@ -1191,11 +1225,13 @@ func TestResolvePolicy(t *testing.T) {
|
||||
toResolve: ptr.To(Group("group:testgroup")),
|
||||
nodes: types.Nodes{
|
||||
{
|
||||
User: users["groupuser1"],
|
||||
User: ptr.To(users["groupuser1"]),
|
||||
UserID: ptr.To(users["groupuser1"].ID),
|
||||
IPv4: ap("100.100.101.203"),
|
||||
},
|
||||
{
|
||||
User: users["groupuser2"],
|
||||
User: ptr.To(users["groupuser2"]),
|
||||
UserID: ptr.To(users["groupuser2"].ID),
|
||||
IPv4: ap("100.100.101.204"),
|
||||
},
|
||||
},
|
||||
@ -1216,7 +1252,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
toResolve: ptr.To(Username("invaliduser@")),
|
||||
nodes: types.Nodes{
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
IPv4: ap("100.100.101.103"),
|
||||
},
|
||||
},
|
||||
@ -1227,7 +1264,7 @@ func TestResolvePolicy(t *testing.T) {
|
||||
toResolve: tp("tag:invalid"),
|
||||
nodes: types.Nodes{
|
||||
{
|
||||
ForcedTags: []string{"tag:test"},
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.234"),
|
||||
},
|
||||
},
|
||||
@ -1248,18 +1285,21 @@ func TestResolvePolicy(t *testing.T) {
|
||||
nodes: types.Nodes{
|
||||
// Node with no tags (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
// Node with forced tags (should be excluded)
|
||||
{
|
||||
User: users["testuser"],
|
||||
ForcedTags: []string{"tag:test"},
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
// Node with allowed requested tag (should be excluded)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:test"},
|
||||
},
|
||||
@ -1267,7 +1307,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with non-allowed requested tag (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:notallowed"},
|
||||
},
|
||||
@ -1275,7 +1316,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with multiple requested tags, one allowed (should be excluded)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:test", "tag:notallowed"},
|
||||
},
|
||||
@ -1283,7 +1325,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with multiple requested tags, none allowed (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:notallowed1", "tag:notallowed2"},
|
||||
},
|
||||
@ -1307,18 +1350,21 @@ func TestResolvePolicy(t *testing.T) {
|
||||
nodes: types.Nodes{
|
||||
// Node with no tags (should be excluded)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
// Node with forced tag (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
ForcedTags: []string{"tag:test"},
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
// Node with allowed requested tag (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:test"},
|
||||
},
|
||||
@ -1326,7 +1372,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with non-allowed requested tag (should be excluded)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:notallowed"},
|
||||
},
|
||||
@ -1334,7 +1381,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with multiple requested tags, one allowed (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:test", "tag:notallowed"},
|
||||
},
|
||||
@ -1342,7 +1390,8 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with multiple requested tags, none allowed (should be excluded)
|
||||
{
|
||||
User: users["testuser"],
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RequestTags: []string{"tag:notallowed1", "tag:notallowed2"},
|
||||
},
|
||||
@ -1350,8 +1399,9 @@ func TestResolvePolicy(t *testing.T) {
|
||||
},
|
||||
// Node with multiple forced tags (should be included)
|
||||
{
|
||||
User: users["testuser"],
|
||||
ForcedTags: []string{"tag:test", "tag:other"},
|
||||
User: ptr.To(users["testuser"]),
|
||||
UserID: ptr.To(users["testuser"].ID),
|
||||
Tags: []string{"tag:test", "tag:other"},
|
||||
IPv4: ap("100.100.101.7"),
|
||||
},
|
||||
},
|
||||
@ -1414,23 +1464,26 @@ func TestResolveAutoApprovers(t *testing.T) {
|
||||
nodes := types.Nodes{
|
||||
{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.4"),
|
||||
ForcedTags: []string{"tag:testtag"},
|
||||
Tags: []string{"tag:testtag"},
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.5"),
|
||||
ForcedTags: []string{"tag:exittest"},
|
||||
Tags: []string{"tag:exittest"},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1604,15 +1657,18 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
||||
nodes := types.Nodes{
|
||||
{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
}
|
||||
|
||||
@ -1737,15 +1793,18 @@ func TestResolveTagOwners(t *testing.T) {
|
||||
nodes := types.Nodes{
|
||||
{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
}
|
||||
|
||||
@ -1822,15 +1881,18 @@ func TestNodeCanHaveTag(t *testing.T) {
|
||||
nodes := types.Nodes{
|
||||
{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
User: users[0],
|
||||
User: &users[0],
|
||||
UserID: &users[0].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
User: users[1],
|
||||
User: &users[1],
|
||||
UserID: &users[1].ID,
|
||||
},
|
||||
{
|
||||
IPv4: ap("100.64.0.3"),
|
||||
User: users[2],
|
||||
User: &users[2],
|
||||
UserID: &users[2].ID,
|
||||
},
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user