diff --git a/acls.go b/acls.go index 6d31066..43d43fb 100644 --- a/acls.go +++ b/acls.go @@ -424,7 +424,7 @@ func parseProtocol(protocol string) ([]int, bool, error) { } // expandalias has an input of either -// - a namespace +// - a user // - a group // - a tag // and transform these in IPAddresses. @@ -444,12 +444,12 @@ func expandAlias( Msg("Expanding") if strings.HasPrefix(alias, "group:") { - namespaces, err := expandGroup(aclPolicy, alias, stripEmailDomain) + users, err := expandGroup(aclPolicy, alias, stripEmailDomain) if err != nil { return ips, err } - for _, n := range namespaces { - nodes := filterMachinesByNamespace(machines, n) + for _, n := range users { + nodes := filterMachinesByUser(machines, n) for _, node := range nodes { ips = append(ips, node.IPAddresses.ToStringSlice()...) } @@ -485,8 +485,8 @@ func expandAlias( } // filter out machines per tag owner - for _, namespace := range owners { - machines := filterMachinesByNamespace(machines, namespace) + for _, user := range owners { + machines := filterMachinesByUser(machines, user) for _, machine := range machines { hi := machine.GetHostInfo() if contains(hi.RequestTags, alias) { @@ -498,8 +498,8 @@ func expandAlias( return ips, nil } - // if alias is a namespace - nodes := filterMachinesByNamespace(machines, alias) + // if alias is a user + nodes := filterMachinesByUser(machines, alias) nodes = excludeCorrectlyTaggedNodes(aclPolicy, nodes, alias, stripEmailDomain) for _, n := range nodes { @@ -532,20 +532,20 @@ func expandAlias( } // excludeCorrectlyTaggedNodes will remove from the list of input nodes the ones -// that are correctly tagged since they should not be listed as being in the namespace -// we assume in this function that we only have nodes from 1 namespace. +// that are correctly tagged since they should not be listed as being in the user +// we assume in this function that we only have nodes from 1 user. func excludeCorrectlyTaggedNodes( aclPolicy ACLPolicy, nodes []Machine, - namespace string, + user string, stripEmailDomain bool, ) []Machine { out := []Machine{} tags := []string{} for tag := range aclPolicy.TagOwners { - owners, _ := expandTagOwners(aclPolicy, namespace, stripEmailDomain) - ns := append(owners, namespace) - if contains(ns, namespace) { + owners, _ := expandTagOwners(aclPolicy, user, stripEmailDomain) + ns := append(owners, user) + if contains(ns, user) { tags = append(tags, tag) } } @@ -619,10 +619,10 @@ func expandPorts(portsStr string, needsWildcard bool) (*[]tailcfg.PortRange, err return &ports, nil } -func filterMachinesByNamespace(machines []Machine, namespace string) []Machine { +func filterMachinesByUser(machines []Machine, user string) []Machine { out := []Machine{} for _, machine := range machines { - if machine.Namespace.Name == namespace { + if machine.User.Name == user { out = append(out, machine) } } @@ -630,7 +630,7 @@ func filterMachinesByNamespace(machines []Machine, namespace string) []Machine { return out } -// expandTagOwners will return a list of namespace. An owner can be either a namespace or a group +// expandTagOwners will return a list of user. An owner can be either a user or a group // a group cannot be composed of groups. func expandTagOwners( aclPolicy ACLPolicy, @@ -661,7 +661,7 @@ func expandTagOwners( return owners, nil } -// expandGroup will return the list of namespace inside the group +// expandGroup will return the list of user inside the group // after some validation. func expandGroup( aclPolicy ACLPolicy, diff --git a/acls_test.go b/acls_test.go index c11e074..34d4085 100644 --- a/acls_test.go +++ b/acls_test.go @@ -77,10 +77,10 @@ func (s *Suite) TestInvalidAction(c *check.C) { func (s *Suite) TestSshRules(c *check.C) { envknob.Setenv("HEADSCALE_EXPERIMENTAL_FEATURE_SSH", "1") - namespace, err := app.CreateNamespace("user1") + user, err := app.CreateUser("user1") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("user1", "testmachine") @@ -98,7 +98,7 @@ func (s *Suite) TestSshRules(c *check.C) { DiscoKey: "faa", Hostname: "testmachine", IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -187,10 +187,10 @@ func (s *Suite) TestInvalidTagOwners(c *check.C) { // match properly the IP's of the related hosts. The owner is valid and the tag is also valid. // the tag is matched in the Sources section. func (s *Suite) TestValidExpandTagOwnersInSources(c *check.C) { - namespace, err := app.CreateNamespace("user1") + user, err := app.CreateUser("user1") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("user1", "testmachine") @@ -208,7 +208,7 @@ func (s *Suite) TestValidExpandTagOwnersInSources(c *check.C) { DiscoKey: "faa", Hostname: "testmachine", IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -237,10 +237,10 @@ func (s *Suite) TestValidExpandTagOwnersInSources(c *check.C) { // match properly the IP's of the related hosts. The owner is valid and the tag is also valid. // the tag is matched in the Destinations section. func (s *Suite) TestValidExpandTagOwnersInDestinations(c *check.C) { - namespace, err := app.CreateNamespace("user1") + user, err := app.CreateUser("user1") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("user1", "testmachine") @@ -258,7 +258,7 @@ func (s *Suite) TestValidExpandTagOwnersInDestinations(c *check.C) { DiscoKey: "faa", Hostname: "testmachine", IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -284,13 +284,13 @@ func (s *Suite) TestValidExpandTagOwnersInDestinations(c *check.C) { } // need a test with: -// tag on a host that isn't owned by a tag owners. So the namespace +// tag on a host that isn't owned by a tag owners. So the user // of the host should be valid. -func (s *Suite) TestInvalidTagValidNamespace(c *check.C) { - namespace, err := app.CreateNamespace("user1") +func (s *Suite) TestInvalidTagValidUser(c *check.C) { + user, err := app.CreateUser("user1") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("user1", "testmachine") @@ -308,7 +308,7 @@ func (s *Suite) TestInvalidTagValidNamespace(c *check.C) { DiscoKey: "faa", Hostname: "testmachine", IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -333,13 +333,13 @@ func (s *Suite) TestInvalidTagValidNamespace(c *check.C) { } // tag on a host is owned by a tag owner, the tag is valid. -// an ACL rule is matching the tag to a namespace. It should not be valid since the +// an ACL rule is matching the tag to a user. It should not be valid since the // host should be tied to the tag now. -func (s *Suite) TestValidTagInvalidNamespace(c *check.C) { - namespace, err := app.CreateNamespace("user1") +func (s *Suite) TestValidTagInvalidUser(c *check.C) { + user, err := app.CreateUser("user1") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("user1", "webserver") @@ -357,7 +357,7 @@ func (s *Suite) TestValidTagInvalidNamespace(c *check.C) { DiscoKey: "faa", Hostname: "webserver", IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -376,7 +376,7 @@ func (s *Suite) TestValidTagInvalidNamespace(c *check.C) { DiscoKey: "faab", Hostname: "user", IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.2")}, - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo2), @@ -467,14 +467,14 @@ func (s *Suite) TestPortWildcardYAML(c *check.C) { c.Assert(rules[0].SrcIPs[0], check.Equals, "*") } -func (s *Suite) TestPortNamespace(c *check.C) { - namespace, err := app.CreateNamespace("testnamespace") +func (s *Suite) TestPortUser(c *check.C) { + user, err := app.CreateUser("testuser") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) - _, err = app.GetMachine("testnamespace", "testmachine") + _, err = app.GetMachine("testuser", "testmachine") c.Assert(err, check.NotNil) ips, _ := app.getAvailableIPs() machine := Machine{ @@ -483,7 +483,7 @@ func (s *Suite) TestPortNamespace(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, IPAddresses: ips, AuthKeyID: uint(pak.ID), @@ -491,7 +491,7 @@ func (s *Suite) TestPortNamespace(c *check.C) { app.db.Save(&machine) err = app.LoadACLPolicy( - "./tests/acls/acl_policy_basic_namespace_as_user.hujson", + "./tests/acls/acl_policy_basic_user_as_user.hujson", ) c.Assert(err, check.IsNil) @@ -513,13 +513,13 @@ func (s *Suite) TestPortNamespace(c *check.C) { } func (s *Suite) TestPortGroup(c *check.C) { - namespace, err := app.CreateNamespace("testnamespace") + user, err := app.CreateUser("testuser") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) - _, err = app.GetMachine("testnamespace", "testmachine") + _, err = app.GetMachine("testuser", "testmachine") c.Assert(err, check.NotNil) ips, _ := app.getAvailableIPs() machine := Machine{ @@ -528,7 +528,7 @@ func (s *Suite) TestPortGroup(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, IPAddresses: ips, AuthKeyID: uint(pak.ID), @@ -689,7 +689,7 @@ func Test_expandTagOwners(t *testing.T) { wantErr: false, }, { - name: "expand with namespace and group", + name: "expand with user and group", args: args{ aclPolicy: ACLPolicy{ Groups: Groups{"group:foo": []string{"user1", "user2"}}, @@ -843,10 +843,10 @@ func Test_expandPorts(t *testing.T) { } } -func Test_listMachinesInNamespace(t *testing.T) { +func Test_listMachinesInUser(t *testing.T) { type args struct { machines []Machine - namespace string + user string } tests := []struct { name string @@ -854,54 +854,54 @@ func Test_listMachinesInNamespace(t *testing.T) { want []Machine }{ { - name: "1 machine in namespace", + name: "1 machine in user", args: args{ machines: []Machine{ - {Namespace: Namespace{Name: "joe"}}, + {User: User{Name: "joe"}}, }, - namespace: "joe", + user: "joe", }, want: []Machine{ - {Namespace: Namespace{Name: "joe"}}, + {User: User{Name: "joe"}}, }, }, { - name: "3 machines, 2 in namespace", + name: "3 machines, 2 in user", args: args{ machines: []Machine{ - {ID: 1, Namespace: Namespace{Name: "joe"}}, - {ID: 2, Namespace: Namespace{Name: "marc"}}, - {ID: 3, Namespace: Namespace{Name: "marc"}}, + {ID: 1, User: User{Name: "joe"}}, + {ID: 2, User: User{Name: "marc"}}, + {ID: 3, User: User{Name: "marc"}}, }, - namespace: "marc", + user: "marc", }, want: []Machine{ - {ID: 2, Namespace: Namespace{Name: "marc"}}, - {ID: 3, Namespace: Namespace{Name: "marc"}}, + {ID: 2, User: User{Name: "marc"}}, + {ID: 3, User: User{Name: "marc"}}, }, }, { - name: "5 machines, 0 in namespace", + name: "5 machines, 0 in user", args: args{ machines: []Machine{ - {ID: 1, Namespace: Namespace{Name: "joe"}}, - {ID: 2, Namespace: Namespace{Name: "marc"}}, - {ID: 3, Namespace: Namespace{Name: "marc"}}, - {ID: 4, Namespace: Namespace{Name: "marc"}}, - {ID: 5, Namespace: Namespace{Name: "marc"}}, + {ID: 1, User: User{Name: "joe"}}, + {ID: 2, User: User{Name: "marc"}}, + {ID: 3, User: User{Name: "marc"}}, + {ID: 4, User: User{Name: "marc"}}, + {ID: 5, User: User{Name: "marc"}}, }, - namespace: "mickael", + user: "mickael", }, want: []Machine{}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - if got := filterMachinesByNamespace(test.args.machines, test.args.namespace); !reflect.DeepEqual( + if got := filterMachinesByUser(test.args.machines, test.args.user); !reflect.DeepEqual( got, test.want, ) { - t.Errorf("listMachinesInNamespace() = %v, want %v", got, test.want) + t.Errorf("listMachinesInUser() = %v, want %v", got, test.want) } }) } @@ -947,25 +947,25 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, aclPolicy: ACLPolicy{ @@ -985,25 +985,25 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, aclPolicy: ACLPolicy{ @@ -1071,7 +1071,7 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1082,7 +1082,7 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1093,13 +1093,13 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, aclPolicy: ACLPolicy{ @@ -1119,25 +1119,25 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, aclPolicy: ACLPolicy{ @@ -1160,27 +1160,27 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, ForcedTags: []string{"tag:hr-webserver"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, ForcedTags: []string{"tag:hr-webserver"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, aclPolicy: ACLPolicy{}, @@ -1198,14 +1198,14 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, ForcedTags: []string{"tag:hr-webserver"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1216,13 +1216,13 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, aclPolicy: ACLPolicy{ @@ -1236,7 +1236,7 @@ func Test_expandAlias(t *testing.T) { wantErr: false, }, { - name: "list host in namespace without correctly tagged servers", + name: "list host in user without correctly tagged servers", args: args{ alias: "joe", machines: []Machine{ @@ -1244,7 +1244,7 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1255,7 +1255,7 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1266,13 +1266,13 @@ func Test_expandAlias(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, aclPolicy: ACLPolicy{ @@ -1308,7 +1308,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { type args struct { aclPolicy ACLPolicy nodes []Machine - namespace string + user string stripEmailDomain bool } tests := []struct { @@ -1328,7 +1328,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1339,7 +1339,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1350,16 +1350,16 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, - namespace: "joe", + user: "joe", stripEmailDomain: true, }, want: []Machine{ { IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.4")}, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, }, @@ -1379,7 +1379,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1390,7 +1390,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1401,16 +1401,16 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, - namespace: "joe", + user: "joe", stripEmailDomain: true, }, want: []Machine{ { IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.4")}, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, }, @@ -1425,7 +1425,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "foo", @@ -1436,23 +1436,23 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, ForcedTags: []string{"tag:accountant-webserver"}, }, { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, - namespace: "joe", + user: "joe", stripEmailDomain: true, }, want: []Machine{ { IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.4")}, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, }, @@ -1467,7 +1467,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "hr-web1", @@ -1478,7 +1478,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "hr-web2", @@ -1489,10 +1489,10 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, - namespace: "joe", + user: "joe", stripEmailDomain: true, }, want: []Machine{ @@ -1500,7 +1500,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "hr-web1", @@ -1511,7 +1511,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, HostInfo: HostInfo{ OS: "centos", Hostname: "hr-web2", @@ -1522,7 +1522,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.4"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, }, @@ -1532,7 +1532,7 @@ func Test_excludeCorrectlyTaggedNodes(t *testing.T) { got := excludeCorrectlyTaggedNodes( test.args.aclPolicy, test.args.nodes, - test.args.namespace, + test.args.user, test.args.stripEmailDomain, ) if !reflect.DeepEqual(got, test.want) { diff --git a/acls_types.go b/acls_types.go index da981d3..4f318dd 100644 --- a/acls_types.go +++ b/acls_types.go @@ -34,7 +34,7 @@ type Groups map[string][]string // Hosts are alias for IP addresses or subnets. type Hosts map[string]netip.Prefix -// TagOwners specify what users (namespaces?) are allow to use certain tags. +// TagOwners specify what users (users?) are allow to use certain tags. type TagOwners map[string][]string // ACLTest is not implemented, but should be use to check if a certain rule is allowed. @@ -44,7 +44,7 @@ type ACLTest struct { Deny []string `json:"deny,omitempty" yaml:"deny,omitempty"` } -// AutoApprovers specify which users (namespaces?), groups or tags have their advertised routes +// AutoApprovers specify which users (users?), groups or tags have their advertised routes // or exit node status automatically enabled. type AutoApprovers struct { Routes map[string][]string `json:"routes" yaml:"routes"` @@ -119,7 +119,7 @@ func (policy ACLPolicy) IsZero() bool { return false } -// Returns the list of autoApproving namespaces, groups or tags for a given IPPrefix. +// Returns the list of autoApproving users, groups or tags for a given IPPrefix. func (autoApprovers *AutoApprovers) GetRouteApprovers( prefix netip.Prefix, ) ([]string, error) { diff --git a/api_key.go b/api_key.go index 01291d7..ae19eb9 100644 --- a/api_key.go +++ b/api_key.go @@ -29,7 +29,7 @@ type APIKey struct { LastSeen *time.Time } -// CreateAPIKey creates a new ApiKey in a namespace, and returns it. +// CreateAPIKey creates a new ApiKey in a user, and returns it. func (h *Headscale) CreateAPIKey( expiration *time.Time, ) (string, *APIKey, error) { @@ -64,7 +64,7 @@ func (h *Headscale) CreateAPIKey( return keyStr, &key, nil } -// ListAPIKeys returns the list of ApiKeys for a namespace. +// ListAPIKeys returns the list of ApiKeys for a user. func (h *Headscale) ListAPIKeys() ([]APIKey, error) { keys := []APIKey{} if err := h.db.Find(&keys).Error; err != nil { diff --git a/app.go b/app.go index 3c48b8b..47a8870 100644 --- a/app.go +++ b/app.go @@ -238,20 +238,20 @@ func (h *Headscale) failoverSubnetRoutes(milliSeconds int64) { } func (h *Headscale) expireEphemeralNodesWorker() { - namespaces, err := h.ListNamespaces() + users, err := h.ListUsers() if err != nil { - log.Error().Err(err).Msg("Error listing namespaces") + log.Error().Err(err).Msg("Error listing users") return } - for _, namespace := range namespaces { - machines, err := h.ListMachinesInNamespace(namespace.Name) + for _, user := range users { + machines, err := h.ListMachinesByUser(user.Name) if err != nil { log.Error(). Err(err). - Str("namespace", namespace.Name). - Msg("Error listing machines in namespace") + Str("user", user.Name). + Msg("Error listing machines in user") return } @@ -283,20 +283,20 @@ func (h *Headscale) expireEphemeralNodesWorker() { } func (h *Headscale) expireExpiredMachinesWorker() { - namespaces, err := h.ListNamespaces() + users, err := h.ListUsers() if err != nil { - log.Error().Err(err).Msg("Error listing namespaces") + log.Error().Err(err).Msg("Error listing users") return } - for _, namespace := range namespaces { - machines, err := h.ListMachinesInNamespace(namespace.Name) + for _, user := range users { + machines, err := h.ListMachinesByUser(user.Name) if err != nil { log.Error(). Err(err). - Str("namespace", namespace.Name). - Msg("Error listing machines in namespace") + Str("user", user.Name). + Msg("Error listing machines in user") return } @@ -304,7 +304,7 @@ func (h *Headscale) expireExpiredMachinesWorker() { expiredFound := false for index, machine := range machines { if machine.isExpired() && - machine.Expiry.After(h.getLastStateChange(namespace)) { + machine.Expiry.After(h.getLastStateChange(user)) { expiredFound = true err := h.ExpireMachine(&machines[index]) @@ -908,31 +908,31 @@ func (h *Headscale) setLastStateChangeToNow() { now := time.Now().UTC() - namespaces, err := h.ListNamespaces() + users, err := h.ListUsers() if err != nil { log.Error(). Caller(). Err(err). - Msg("failed to fetch all namespaces, failing to update last changed state.") + Msg("failed to fetch all users, failing to update last changed state.") } - for _, namespace := range namespaces { - lastStateUpdate.WithLabelValues(namespace.Name, "headscale").Set(float64(now.Unix())) + for _, user := range users { + lastStateUpdate.WithLabelValues(user.Name, "headscale").Set(float64(now.Unix())) if h.lastStateChange == nil { h.lastStateChange = xsync.NewMapOf[time.Time]() } - h.lastStateChange.Store(namespace.Name, now) + h.lastStateChange.Store(user.Name, now) } } -func (h *Headscale) getLastStateChange(namespaces ...Namespace) time.Time { +func (h *Headscale) getLastStateChange(users ...User) time.Time { times := []time.Time{} - // getLastStateChange takes a list of namespaces as a "filter", if no namespaces - // are past, then use the entier list of namespaces and look for the last update - if len(namespaces) > 0 { - for _, namespace := range namespaces { - if lastChange, ok := h.lastStateChange.Load(namespace.Name); ok { + // getLastStateChange takes a list of users as a "filter", if no users + // are past, then use the entier list of users and look for the last update + if len(users) > 0 { + for _, user := range users { + if lastChange, ok := h.lastStateChange.Load(user.Name); ok { times = append(times, lastChange) } } diff --git a/cmd/gh-action-integration-generator/main.go b/cmd/gh-action-integration-generator/main.go index 72bffa1..2bc8b31 100644 --- a/cmd/gh-action-integration-generator/main.go +++ b/cmd/gh-action-integration-generator/main.go @@ -77,7 +77,7 @@ func main() { "TestCreateTailscale", "TestEnablingRoutes", "TestHeadscale", - "TestNamespaceCommand", + "TestUserCommand", "TestOIDCAuthenticationPingAll", "TestOIDCExpireNodes", "TestPingAllByHostname", @@ -87,10 +87,10 @@ func main() { "TestPreAuthKeyCommandWithoutExpiry", "TestResolveMagicDNS", "TestSSHIsBlockedInACL", - "TestSSHMultipleNamespacesAllToAll", + "TestSSHMultipleUsersAllToAll", "TestSSHNoSSHConfigured", - "TestSSHOneNamespaceAllToAll", - "TestSSNamespaceOnlyIsolation", + "TestSSHOneUserAllToAll", + "TestSSUserOnlyIsolation", "TestTaildrop", "TestTailscaleNodesJoiningHeadcale", } diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go index 0e0e6ff..a275072 100644 --- a/cmd/headscale/cli/debug.go +++ b/cmd/headscale/cli/debug.go @@ -27,8 +27,8 @@ func init() { if err != nil { log.Fatal().Err(err).Msg("") } - createNodeCmd.Flags().StringP("namespace", "n", "", "Namespace") - err = createNodeCmd.MarkFlagRequired("namespace") + createNodeCmd.Flags().StringP("user", "n", "", "User") + err = createNodeCmd.MarkFlagRequired("user") if err != nil { log.Fatal().Err(err).Msg("") } @@ -55,9 +55,9 @@ var createNodeCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting user: %s", err), output) return } @@ -112,7 +112,7 @@ var createNodeCmd = &cobra.Command{ request := &v1.DebugCreateMachineRequest{ Key: machineKey, Name: name, - Namespace: namespace, + User: user, Routes: routes, } diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go index 729e213..59f5976 100644 --- a/cmd/headscale/cli/namespaces.go +++ b/cmd/headscale/cli/namespaces.go @@ -13,26 +13,26 @@ import ( ) func init() { - rootCmd.AddCommand(namespaceCmd) - namespaceCmd.AddCommand(createNamespaceCmd) - namespaceCmd.AddCommand(listNamespacesCmd) - namespaceCmd.AddCommand(destroyNamespaceCmd) - namespaceCmd.AddCommand(renameNamespaceCmd) + rootCmd.AddCommand(userCmd) + userCmd.AddCommand(createUserCmd) + userCmd.AddCommand(listUsersCmd) + userCmd.AddCommand(destroyUserCmd) + userCmd.AddCommand(renameUserCmd) } const ( errMissingParameter = headscale.Error("missing parameters") ) -var namespaceCmd = &cobra.Command{ - Use: "namespaces", - Short: "Manage the namespaces of Headscale", - Aliases: []string{"namespace", "ns", "user", "users"}, +var userCmd = &cobra.Command{ + Use: "users", + Short: "Manage the users of Headscale", + Aliases: []string{"user", "ns", "user", "users"}, } -var createNamespaceCmd = &cobra.Command{ +var createUserCmd = &cobra.Command{ Use: "create NAME", - Short: "Creates a new namespace", + Short: "Creates a new user", Aliases: []string{"c", "new"}, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { @@ -44,7 +44,7 @@ var createNamespaceCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespaceName := args[0] + userName := args[0] ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() @@ -52,15 +52,15 @@ var createNamespaceCmd = &cobra.Command{ log.Trace().Interface("client", client).Msg("Obtained gRPC client") - request := &v1.CreateNamespaceRequest{Name: namespaceName} + request := &v1.CreateUserRequest{Name: userName} - log.Trace().Interface("request", request).Msg("Sending CreateNamespace request") - response, err := client.CreateNamespace(ctx, request) + log.Trace().Interface("request", request).Msg("Sending CreateUser request") + response, err := client.CreateUser(ctx, request) if err != nil { ErrorOutput( err, fmt.Sprintf( - "Cannot create namespace: %s", + "Cannot create user: %s", status.Convert(err).Message(), ), output, @@ -69,13 +69,13 @@ var createNamespaceCmd = &cobra.Command{ return } - SuccessOutput(response.Namespace, "Namespace created", output) + SuccessOutput(response.User, "User created", output) }, } -var destroyNamespaceCmd = &cobra.Command{ +var destroyUserCmd = &cobra.Command{ Use: "destroy NAME", - Short: "Destroys a namespace", + Short: "Destroys a user", Aliases: []string{"delete"}, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { @@ -87,17 +87,17 @@ var destroyNamespaceCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespaceName := args[0] + userName := args[0] - request := &v1.GetNamespaceRequest{ - Name: namespaceName, + request := &v1.GetUserRequest{ + Name: userName, } ctx, client, conn, cancel := getHeadscaleCLIClient() defer cancel() defer conn.Close() - _, err := client.GetNamespace(ctx, request) + _, err := client.GetUser(ctx, request) if err != nil { ErrorOutput( err, @@ -113,8 +113,8 @@ var destroyNamespaceCmd = &cobra.Command{ if !force { prompt := &survey.Confirm{ Message: fmt.Sprintf( - "Do you want to remove the namespace '%s' and any associated preauthkeys?", - namespaceName, + "Do you want to remove the user '%s' and any associated preauthkeys?", + userName, ), } err := survey.AskOne(prompt, &confirm) @@ -124,14 +124,14 @@ var destroyNamespaceCmd = &cobra.Command{ } if confirm || force { - request := &v1.DeleteNamespaceRequest{Name: namespaceName} + request := &v1.DeleteUserRequest{Name: userName} - response, err := client.DeleteNamespace(ctx, request) + response, err := client.DeleteUser(ctx, request) if err != nil { ErrorOutput( err, fmt.Sprintf( - "Cannot destroy namespace: %s", + "Cannot destroy user: %s", status.Convert(err).Message(), ), output, @@ -139,16 +139,16 @@ var destroyNamespaceCmd = &cobra.Command{ return } - SuccessOutput(response, "Namespace destroyed", output) + SuccessOutput(response, "User destroyed", output) } else { - SuccessOutput(map[string]string{"Result": "Namespace not destroyed"}, "Namespace not destroyed", output) + SuccessOutput(map[string]string{"Result": "User not destroyed"}, "User not destroyed", output) } }, } -var listNamespacesCmd = &cobra.Command{ +var listUsersCmd = &cobra.Command{ Use: "list", - Short: "List all the namespaces", + Short: "List all the users", Aliases: []string{"ls", "show"}, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") @@ -157,13 +157,13 @@ var listNamespacesCmd = &cobra.Command{ defer cancel() defer conn.Close() - request := &v1.ListNamespacesRequest{} + request := &v1.ListUsersRequest{} - response, err := client.ListNamespaces(ctx, request) + response, err := client.ListUsers(ctx, request) if err != nil { ErrorOutput( err, - fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), + fmt.Sprintf("Cannot get users: %s", status.Convert(err).Message()), output, ) @@ -171,19 +171,19 @@ var listNamespacesCmd = &cobra.Command{ } if output != "" { - SuccessOutput(response.Namespaces, "", output) + SuccessOutput(response.Users, "", output) return } tableData := pterm.TableData{{"ID", "Name", "Created"}} - for _, namespace := range response.GetNamespaces() { + for _, user := range response.GetUsers() { tableData = append( tableData, []string{ - namespace.GetId(), - namespace.GetName(), - namespace.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"), + user.GetId(), + user.GetName(), + user.GetCreatedAt().AsTime().Format("2006-01-02 15:04:05"), }, ) } @@ -200,9 +200,9 @@ var listNamespacesCmd = &cobra.Command{ }, } -var renameNamespaceCmd = &cobra.Command{ +var renameUserCmd = &cobra.Command{ Use: "rename OLD_NAME NEW_NAME", - Short: "Renames a namespace", + Short: "Renames a user", Aliases: []string{"mv"}, Args: func(cmd *cobra.Command, args []string) error { expectedArguments := 2 @@ -219,17 +219,17 @@ var renameNamespaceCmd = &cobra.Command{ defer cancel() defer conn.Close() - request := &v1.RenameNamespaceRequest{ + request := &v1.RenameUserRequest{ OldName: args[0], NewName: args[1], } - response, err := client.RenameNamespace(ctx, request) + response, err := client.RenameUser(ctx, request) if err != nil { ErrorOutput( err, fmt.Sprintf( - "Cannot rename namespace: %s", + "Cannot rename user: %s", status.Convert(err).Message(), ), output, @@ -238,6 +238,6 @@ var renameNamespaceCmd = &cobra.Command{ return } - SuccessOutput(response.Namespace, "Namespace renamed", output) + SuccessOutput(response.User, "User renamed", output) }, } diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 35d0d28..039f05a 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -19,12 +19,12 @@ import ( func init() { rootCmd.AddCommand(nodeCmd) - listNodesCmd.Flags().StringP("namespace", "n", "", "Filter by namespace") + listNodesCmd.Flags().StringP("user", "n", "", "Filter by user") listNodesCmd.Flags().BoolP("tags", "t", false, "Show tags") nodeCmd.AddCommand(listNodesCmd) - registerNodeCmd.Flags().StringP("namespace", "n", "", "Namespace") - err := registerNodeCmd.MarkFlagRequired("namespace") + registerNodeCmd.Flags().StringP("user", "n", "", "User") + err := registerNodeCmd.MarkFlagRequired("user") if err != nil { log.Fatalf(err.Error()) } @@ -63,9 +63,9 @@ func init() { log.Fatalf(err.Error()) } - moveNodeCmd.Flags().StringP("namespace", "n", "", "New namespace") + moveNodeCmd.Flags().StringP("user", "n", "", "New user") - err = moveNodeCmd.MarkFlagRequired("namespace") + err = moveNodeCmd.MarkFlagRequired("user") if err != nil { log.Fatalf(err.Error()) } @@ -93,9 +93,9 @@ var registerNodeCmd = &cobra.Command{ Short: "Registers a machine to your network", Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting user: %s", err), output) return } @@ -117,7 +117,7 @@ var registerNodeCmd = &cobra.Command{ request := &v1.RegisterMachineRequest{ Key: machineKey, - Namespace: namespace, + User: user, } response, err := client.RegisterMachine(ctx, request) @@ -146,9 +146,9 @@ var listNodesCmd = &cobra.Command{ Aliases: []string{"ls", "show"}, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting user: %s", err), output) return } @@ -164,7 +164,7 @@ var listNodesCmd = &cobra.Command{ defer conn.Close() request := &v1.ListMachinesRequest{ - Namespace: namespace, + User: user, } response, err := client.ListMachines(ctx, request) @@ -184,7 +184,7 @@ var listNodesCmd = &cobra.Command{ return } - tableData, err := nodesToPtables(namespace, showTags, response.Machines) + tableData, err := nodesToPtables(user, showTags, response.Machines) if err != nil { ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) @@ -388,7 +388,7 @@ var deleteNodeCmd = &cobra.Command{ var moveNodeCmd = &cobra.Command{ Use: "move", - Short: "Move node to another namespace", + Short: "Move node to another user", Aliases: []string{"mv"}, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") @@ -404,11 +404,11 @@ var moveNodeCmd = &cobra.Command{ return } - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { ErrorOutput( err, - fmt.Sprintf("Error getting namespace: %s", err), + fmt.Sprintf("Error getting user: %s", err), output, ) @@ -439,7 +439,7 @@ var moveNodeCmd = &cobra.Command{ moveRequest := &v1.MoveMachineRequest{ MachineId: identifier, - Namespace: namespace, + User: user, } moveResponse, err := client.MoveMachine(ctx, moveRequest) @@ -456,12 +456,12 @@ var moveNodeCmd = &cobra.Command{ return } - SuccessOutput(moveResponse.Machine, "Node moved to another namespace", output) + SuccessOutput(moveResponse.Machine, "Node moved to another user", output) }, } func nodesToPtables( - currentNamespace string, + currentUser string, showTags bool, machines []*v1.Machine, ) (pterm.TableData, error) { @@ -471,7 +471,7 @@ func nodesToPtables( "Name", "MachineKey", "NodeKey", - "Namespace", + "User", "IP addresses", "Ephemeral", "Last seen", @@ -560,12 +560,12 @@ func nodesToPtables( } validTags = strings.TrimLeft(validTags, ",") - var namespace string - if currentNamespace == "" || (currentNamespace == machine.Namespace.Name) { - namespace = pterm.LightMagenta(machine.Namespace.Name) + var user string + if currentUser == "" || (currentUser == machine.User.Name) { + user = pterm.LightMagenta(machine.User.Name) } else { - // Shared into this namespace - namespace = pterm.LightYellow(machine.Namespace.Name) + // Shared into this user + user = pterm.LightYellow(machine.User.Name) } var IPV4Address string @@ -584,7 +584,7 @@ func nodesToPtables( machine.GetGivenName(), machineKey.ShortString(), nodeKey.ShortString(), - namespace, + user, strings.Join([]string{IPV4Address, IPV6Address}, ", "), strconv.FormatBool(ephemeral), lastSeenTime, diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 681731a..7175823 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -20,8 +20,8 @@ const ( func init() { rootCmd.AddCommand(preauthkeysCmd) - preauthkeysCmd.PersistentFlags().StringP("namespace", "n", "", "Namespace") - err := preauthkeysCmd.MarkPersistentFlagRequired("namespace") + preauthkeysCmd.PersistentFlags().StringP("user", "n", "", "User") + err := preauthkeysCmd.MarkPersistentFlagRequired("user") if err != nil { log.Fatal().Err(err).Msg("") } @@ -46,14 +46,14 @@ var preauthkeysCmd = &cobra.Command{ var listPreAuthKeys = &cobra.Command{ Use: "list", - Short: "List the preauthkeys for this namespace", + Short: "List the preauthkeys for this user", Aliases: []string{"ls", "show"}, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting user: %s", err), output) return } @@ -63,7 +63,7 @@ var listPreAuthKeys = &cobra.Command{ defer conn.Close() request := &v1.ListPreAuthKeysRequest{ - Namespace: namespace, + User: user, } response, err := client.ListPreAuthKeys(ctx, request) @@ -143,14 +143,14 @@ var listPreAuthKeys = &cobra.Command{ var createPreAuthKeyCmd = &cobra.Command{ Use: "create", - Short: "Creates a new preauthkey in the specified namespace", + Short: "Creates a new preauthkey in the specified user", Aliases: []string{"c", "new"}, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting user: %s", err), output) return } @@ -162,11 +162,11 @@ var createPreAuthKeyCmd = &cobra.Command{ log.Trace(). Bool("reusable", reusable). Bool("ephemeral", ephemeral). - Str("namespace", namespace). + Str("user", user). Msg("Preparing to create preauthkey") request := &v1.CreatePreAuthKeyRequest{ - Namespace: namespace, + User: user, Reusable: reusable, Ephemeral: ephemeral, AclTags: tags, @@ -225,9 +225,9 @@ var expirePreAuthKeyCmd = &cobra.Command{ }, Run: func(cmd *cobra.Command, args []string) { output, _ := cmd.Flags().GetString("output") - namespace, err := cmd.Flags().GetString("namespace") + user, err := cmd.Flags().GetString("user") if err != nil { - ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) + ErrorOutput(err, fmt.Sprintf("Error getting user: %s", err), output) return } @@ -237,7 +237,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ defer conn.Close() request := &v1.ExpirePreAuthKeyRequest{ - Namespace: namespace, + User: user, Key: args[0], } diff --git a/dns.go b/dns.go index 6636627..da1a95d 100644 --- a/dns.go +++ b/dns.go @@ -190,23 +190,23 @@ func getMapResponseDNSConfig( ) *tailcfg.DNSConfig { var dnsConfig *tailcfg.DNSConfig = dnsConfigOrig.Clone() if dnsConfigOrig != nil && dnsConfigOrig.Proxied { // if MagicDNS is enabled - // Only inject the Search Domain of the current namespace - shared nodes should use their full FQDN + // Only inject the Search Domain of the current user - shared nodes should use their full FQDN dnsConfig.Domains = append( dnsConfig.Domains, fmt.Sprintf( "%s.%s", - machine.Namespace.Name, + machine.User.Name, baseDomain, ), ) - namespaceSet := mapset.NewSet[Namespace]() - namespaceSet.Add(machine.Namespace) + userSet := mapset.NewSet[User]() + userSet.Add(machine.User) for _, p := range peers { - namespaceSet.Add(p.Namespace) + userSet.Add(p.User) } - for _, namespace := range namespaceSet.ToSlice() { - dnsRoute := fmt.Sprintf("%v.%v", namespace.Name, baseDomain) + for _, user := range userSet.ToSlice() { + dnsRoute := fmt.Sprintf("%v.%v", user.Name, baseDomain) dnsConfig.Routes[dnsRoute] = nil } } else { diff --git a/dns_test.go b/dns_test.go index a59cc7e..03b7f47 100644 --- a/dns_test.go +++ b/dns_test.go @@ -112,17 +112,17 @@ func (s *Suite) TestMagicDNSRootDomainsIPv6SingleMultiple(c *check.C) { } func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { - namespaceShared1, err := app.CreateNamespace("shared1") + userShared1, err := app.CreateUser("shared1") c.Assert(err, check.IsNil) - namespaceShared2, err := app.CreateNamespace("shared2") + userShared2, err := app.CreateUser("shared2") c.Assert(err, check.IsNil) - namespaceShared3, err := app.CreateNamespace("shared3") + userShared3, err := app.CreateUser("shared3") c.Assert(err, check.IsNil) preAuthKeyInShared1, err := app.CreatePreAuthKey( - namespaceShared1.Name, + userShared1.Name, false, false, nil, @@ -131,7 +131,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { c.Assert(err, check.IsNil) preAuthKeyInShared2, err := app.CreatePreAuthKey( - namespaceShared2.Name, + userShared2.Name, false, false, nil, @@ -140,7 +140,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { c.Assert(err, check.IsNil) preAuthKeyInShared3, err := app.CreatePreAuthKey( - namespaceShared3.Name, + userShared3.Name, false, false, nil, @@ -149,7 +149,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { c.Assert(err, check.IsNil) PreAuthKey2InShared1, err := app.CreatePreAuthKey( - namespaceShared1.Name, + userShared1.Name, false, false, nil, @@ -157,7 +157,7 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { ) c.Assert(err, check.IsNil) - _, err = app.GetMachine(namespaceShared1.Name, "test_get_shared_nodes_1") + _, err = app.GetMachine(userShared1.Name, "test_get_shared_nodes_1") c.Assert(err, check.NotNil) machineInShared1 := &Machine{ @@ -166,15 +166,15 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", Hostname: "test_get_shared_nodes_1", - NamespaceID: namespaceShared1.ID, - Namespace: *namespaceShared1, + UserID: userShared1.ID, + User: *userShared1, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.1")}, AuthKeyID: uint(preAuthKeyInShared1.ID), } app.db.Save(machineInShared1) - _, err = app.GetMachine(namespaceShared1.Name, machineInShared1.Hostname) + _, err = app.GetMachine(userShared1.Name, machineInShared1.Hostname) c.Assert(err, check.IsNil) machineInShared2 := &Machine{ @@ -183,15 +183,15 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_2", - NamespaceID: namespaceShared2.ID, - Namespace: *namespaceShared2, + UserID: userShared2.ID, + User: *userShared2, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.2")}, AuthKeyID: uint(preAuthKeyInShared2.ID), } app.db.Save(machineInShared2) - _, err = app.GetMachine(namespaceShared2.Name, machineInShared2.Hostname) + _, err = app.GetMachine(userShared2.Name, machineInShared2.Hostname) c.Assert(err, check.IsNil) machineInShared3 := &Machine{ @@ -200,15 +200,15 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_3", - NamespaceID: namespaceShared3.ID, - Namespace: *namespaceShared3, + UserID: userShared3.ID, + User: *userShared3, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.3")}, AuthKeyID: uint(preAuthKeyInShared3.ID), } app.db.Save(machineInShared3) - _, err = app.GetMachine(namespaceShared3.Name, machineInShared3.Hostname) + _, err = app.GetMachine(userShared3.Name, machineInShared3.Hostname) c.Assert(err, check.IsNil) machine2InShared1 := &Machine{ @@ -217,8 +217,8 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_4", - NamespaceID: namespaceShared1.ID, - Namespace: *namespaceShared1, + UserID: userShared1.ID, + User: *userShared1, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.4")}, AuthKeyID: uint(PreAuthKey2InShared1.ID), @@ -245,31 +245,31 @@ func (s *Suite) TestDNSConfigMapResponseWithMagicDNS(c *check.C) { c.Assert(len(dnsConfig.Routes), check.Equals, 3) - domainRouteShared1 := fmt.Sprintf("%s.%s", namespaceShared1.Name, baseDomain) + domainRouteShared1 := fmt.Sprintf("%s.%s", userShared1.Name, baseDomain) _, ok := dnsConfig.Routes[domainRouteShared1] c.Assert(ok, check.Equals, true) - domainRouteShared2 := fmt.Sprintf("%s.%s", namespaceShared2.Name, baseDomain) + domainRouteShared2 := fmt.Sprintf("%s.%s", userShared2.Name, baseDomain) _, ok = dnsConfig.Routes[domainRouteShared2] c.Assert(ok, check.Equals, true) - domainRouteShared3 := fmt.Sprintf("%s.%s", namespaceShared3.Name, baseDomain) + domainRouteShared3 := fmt.Sprintf("%s.%s", userShared3.Name, baseDomain) _, ok = dnsConfig.Routes[domainRouteShared3] c.Assert(ok, check.Equals, true) } func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { - namespaceShared1, err := app.CreateNamespace("shared1") + userShared1, err := app.CreateUser("shared1") c.Assert(err, check.IsNil) - namespaceShared2, err := app.CreateNamespace("shared2") + userShared2, err := app.CreateUser("shared2") c.Assert(err, check.IsNil) - namespaceShared3, err := app.CreateNamespace("shared3") + userShared3, err := app.CreateUser("shared3") c.Assert(err, check.IsNil) preAuthKeyInShared1, err := app.CreatePreAuthKey( - namespaceShared1.Name, + userShared1.Name, false, false, nil, @@ -278,7 +278,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { c.Assert(err, check.IsNil) preAuthKeyInShared2, err := app.CreatePreAuthKey( - namespaceShared2.Name, + userShared2.Name, false, false, nil, @@ -287,7 +287,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { c.Assert(err, check.IsNil) preAuthKeyInShared3, err := app.CreatePreAuthKey( - namespaceShared3.Name, + userShared3.Name, false, false, nil, @@ -296,7 +296,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { c.Assert(err, check.IsNil) preAuthKey2InShared1, err := app.CreatePreAuthKey( - namespaceShared1.Name, + userShared1.Name, false, false, nil, @@ -304,7 +304,7 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { ) c.Assert(err, check.IsNil) - _, err = app.GetMachine(namespaceShared1.Name, "test_get_shared_nodes_1") + _, err = app.GetMachine(userShared1.Name, "test_get_shared_nodes_1") c.Assert(err, check.NotNil) machineInShared1 := &Machine{ @@ -313,15 +313,15 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", Hostname: "test_get_shared_nodes_1", - NamespaceID: namespaceShared1.ID, - Namespace: *namespaceShared1, + UserID: userShared1.ID, + User: *userShared1, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.1")}, AuthKeyID: uint(preAuthKeyInShared1.ID), } app.db.Save(machineInShared1) - _, err = app.GetMachine(namespaceShared1.Name, machineInShared1.Hostname) + _, err = app.GetMachine(userShared1.Name, machineInShared1.Hostname) c.Assert(err, check.IsNil) machineInShared2 := &Machine{ @@ -330,15 +330,15 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_2", - NamespaceID: namespaceShared2.ID, - Namespace: *namespaceShared2, + UserID: userShared2.ID, + User: *userShared2, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.2")}, AuthKeyID: uint(preAuthKeyInShared2.ID), } app.db.Save(machineInShared2) - _, err = app.GetMachine(namespaceShared2.Name, machineInShared2.Hostname) + _, err = app.GetMachine(userShared2.Name, machineInShared2.Hostname) c.Assert(err, check.IsNil) machineInShared3 := &Machine{ @@ -347,15 +347,15 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_3", - NamespaceID: namespaceShared3.ID, - Namespace: *namespaceShared3, + UserID: userShared3.ID, + User: *userShared3, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.3")}, AuthKeyID: uint(preAuthKeyInShared3.ID), } app.db.Save(machineInShared3) - _, err = app.GetMachine(namespaceShared3.Name, machineInShared3.Hostname) + _, err = app.GetMachine(userShared3.Name, machineInShared3.Hostname) c.Assert(err, check.IsNil) machine2InShared1 := &Machine{ @@ -364,8 +364,8 @@ func (s *Suite) TestDNSConfigMapResponseWithoutMagicDNS(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_4", - NamespaceID: namespaceShared1.ID, - Namespace: *namespaceShared1, + UserID: userShared1.ID, + User: *userShared1, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.4")}, AuthKeyID: uint(preAuthKey2InShared1.ID), diff --git a/grpcv1.go b/grpcv1.go index c3936df..38bf181 100644 --- a/grpcv1.go +++ b/grpcv1.go @@ -26,76 +26,76 @@ func newHeadscaleV1APIServer(h *Headscale) v1.HeadscaleServiceServer { } } -func (api headscaleV1APIServer) GetNamespace( +func (api headscaleV1APIServer) GetUser( ctx context.Context, - request *v1.GetNamespaceRequest, -) (*v1.GetNamespaceResponse, error) { - namespace, err := api.h.GetNamespace(request.GetName()) + request *v1.GetUserRequest, +) (*v1.GetUserResponse, error) { + user, err := api.h.GetUser(request.GetName()) if err != nil { return nil, err } - return &v1.GetNamespaceResponse{Namespace: namespace.toProto()}, nil + return &v1.GetUserResponse{User: user.toProto()}, nil } -func (api headscaleV1APIServer) CreateNamespace( +func (api headscaleV1APIServer) CreateUser( ctx context.Context, - request *v1.CreateNamespaceRequest, -) (*v1.CreateNamespaceResponse, error) { - namespace, err := api.h.CreateNamespace(request.GetName()) + request *v1.CreateUserRequest, +) (*v1.CreateUserResponse, error) { + user, err := api.h.CreateUser(request.GetName()) if err != nil { return nil, err } - return &v1.CreateNamespaceResponse{Namespace: namespace.toProto()}, nil + return &v1.CreateUserResponse{User: user.toProto()}, nil } -func (api headscaleV1APIServer) RenameNamespace( +func (api headscaleV1APIServer) RenameUser( ctx context.Context, - request *v1.RenameNamespaceRequest, -) (*v1.RenameNamespaceResponse, error) { - err := api.h.RenameNamespace(request.GetOldName(), request.GetNewName()) + request *v1.RenameUserRequest, +) (*v1.RenameUserResponse, error) { + err := api.h.RenameUser(request.GetOldName(), request.GetNewName()) if err != nil { return nil, err } - namespace, err := api.h.GetNamespace(request.GetNewName()) + user, err := api.h.GetUser(request.GetNewName()) if err != nil { return nil, err } - return &v1.RenameNamespaceResponse{Namespace: namespace.toProto()}, nil + return &v1.RenameUserResponse{User: user.toProto()}, nil } -func (api headscaleV1APIServer) DeleteNamespace( +func (api headscaleV1APIServer) DeleteUser( ctx context.Context, - request *v1.DeleteNamespaceRequest, -) (*v1.DeleteNamespaceResponse, error) { - err := api.h.DestroyNamespace(request.GetName()) + request *v1.DeleteUserRequest, +) (*v1.DeleteUserResponse, error) { + err := api.h.DestroyUser(request.GetName()) if err != nil { return nil, err } - return &v1.DeleteNamespaceResponse{}, nil + return &v1.DeleteUserResponse{}, nil } -func (api headscaleV1APIServer) ListNamespaces( +func (api headscaleV1APIServer) ListUsers( ctx context.Context, - request *v1.ListNamespacesRequest, -) (*v1.ListNamespacesResponse, error) { - namespaces, err := api.h.ListNamespaces() + request *v1.ListUsersRequest, +) (*v1.ListUsersResponse, error) { + users, err := api.h.ListUsers() if err != nil { return nil, err } - response := make([]*v1.Namespace, len(namespaces)) - for index, namespace := range namespaces { - response[index] = namespace.toProto() + response := make([]*v1.User, len(users)) + for index, user := range users { + response[index] = user.toProto() } - log.Trace().Caller().Interface("namespaces", response).Msg("") + log.Trace().Caller().Interface("users", response).Msg("") - return &v1.ListNamespacesResponse{Namespaces: response}, nil + return &v1.ListUsersResponse{Users: response}, nil } func (api headscaleV1APIServer) CreatePreAuthKey( @@ -117,7 +117,7 @@ func (api headscaleV1APIServer) CreatePreAuthKey( } preAuthKey, err := api.h.CreatePreAuthKey( - request.GetNamespace(), + request.GetUser(), request.GetReusable(), request.GetEphemeral(), &expiration, @@ -134,7 +134,7 @@ func (api headscaleV1APIServer) ExpirePreAuthKey( ctx context.Context, request *v1.ExpirePreAuthKeyRequest, ) (*v1.ExpirePreAuthKeyResponse, error) { - preAuthKey, err := api.h.GetPreAuthKey(request.GetNamespace(), request.Key) + preAuthKey, err := api.h.GetPreAuthKey(request.GetUser(), request.Key) if err != nil { return nil, err } @@ -151,7 +151,7 @@ func (api headscaleV1APIServer) ListPreAuthKeys( ctx context.Context, request *v1.ListPreAuthKeysRequest, ) (*v1.ListPreAuthKeysResponse, error) { - preAuthKeys, err := api.h.ListPreAuthKeys(request.GetNamespace()) + preAuthKeys, err := api.h.ListPreAuthKeys(request.GetUser()) if err != nil { return nil, err } @@ -169,13 +169,13 @@ func (api headscaleV1APIServer) RegisterMachine( request *v1.RegisterMachineRequest, ) (*v1.RegisterMachineResponse, error) { log.Trace(). - Str("namespace", request.GetNamespace()). + Str("user", request.GetUser()). Str("node_key", request.GetKey()). Msg("Registering machine") machine, err := api.h.RegisterMachineFromAuthCallback( request.GetKey(), - request.GetNamespace(), + request.GetUser(), nil, RegisterMethodCLI, ) @@ -313,8 +313,8 @@ func (api headscaleV1APIServer) ListMachines( ctx context.Context, request *v1.ListMachinesRequest, ) (*v1.ListMachinesResponse, error) { - if request.GetNamespace() != "" { - machines, err := api.h.ListMachinesInNamespace(request.GetNamespace()) + if request.GetUser() != "" { + machines, err := api.h.ListMachinesByUser(request.GetUser()) if err != nil { return nil, err } @@ -357,7 +357,7 @@ func (api headscaleV1APIServer) MoveMachine( return nil, err } - err = api.h.SetMachineNamespace(machine, request.GetNamespace()) + err = api.h.SetMachineUser(machine, request.GetUser()) if err != nil { return nil, err } @@ -483,7 +483,7 @@ func (api headscaleV1APIServer) DebugCreateMachine( ctx context.Context, request *v1.DebugCreateMachineRequest, ) (*v1.DebugCreateMachineResponse, error) { - namespace, err := api.h.GetNamespace(request.GetNamespace()) + user, err := api.h.GetUser(request.GetUser()) if err != nil { return nil, err } @@ -514,7 +514,7 @@ func (api headscaleV1APIServer) DebugCreateMachine( MachineKey: request.GetKey(), Hostname: request.GetName(), GivenName: givenName, - Namespace: *namespace, + User: *user, Expiry: &time.Time{}, LastSeen: &time.Time{}, diff --git a/integration/auth_oidc_test.go b/integration/auth_oidc_test.go index 6142e2f..e980345 100644 --- a/integration/auth_oidc_test.go +++ b/integration/auth_oidc_test.go @@ -49,7 +49,7 @@ func TestOIDCAuthenticationPingAll(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), + "user1": len(TailscaleVersions), } oidcConfig, err := scenario.runMockOIDC(defaultAccessTTL) @@ -116,7 +116,7 @@ func TestOIDCExpireNodes(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), + "user1": len(TailscaleVersions), } oidcConfig, err := scenario.runMockOIDC(shortAccessTTL) @@ -169,7 +169,7 @@ func TestOIDCExpireNodes(t *testing.T) { } func (s *AuthOIDCScenario) CreateHeadscaleEnv( - namespaces map[string]int, + users map[string]int, opts ...hsic.Option, ) error { headscale, err := s.Headscale(opts...) @@ -182,19 +182,19 @@ func (s *AuthOIDCScenario) CreateHeadscaleEnv( return err } - for namespaceName, clientCount := range namespaces { - log.Printf("creating namespace %s with %d clients", namespaceName, clientCount) - err = s.CreateNamespace(namespaceName) + for userName, clientCount := range users { + log.Printf("creating user %s with %d clients", userName, clientCount) + err = s.CreateUser(userName) if err != nil { return err } - err = s.CreateTailscaleNodesInNamespace(namespaceName, "all", clientCount) + err = s.CreateTailscaleNodesInUser(userName, "all", clientCount) if err != nil { return err } - err = s.runTailscaleUp(namespaceName, headscale.GetEndpoint()) + err = s.runTailscaleUp(userName, headscale.GetEndpoint()) if err != nil { return err } @@ -287,20 +287,20 @@ func (s *AuthOIDCScenario) runMockOIDC(accessTTL time.Duration) (*headscale.OIDC } func (s *AuthOIDCScenario) runTailscaleUp( - namespaceStr, loginServer string, + userStr, loginServer string, ) error { headscale, err := s.Headscale() if err != nil { return err } - log.Printf("running tailscale up for namespace %s", namespaceStr) - if namespace, ok := s.namespaces[namespaceStr]; ok { - for _, client := range namespace.Clients { - namespace.joinWaitGroup.Add(1) + log.Printf("running tailscale up for user %s", userStr) + if user, ok := s.users[userStr]; ok { + for _, client := range user.Clients { + user.joinWaitGroup.Add(1) go func(c TailscaleClient) { - defer namespace.joinWaitGroup.Done() + defer user.joinWaitGroup.Done() // TODO(juanfont): error handle this loginURL, err := c.UpWithLoginURL(loginServer) @@ -347,12 +347,12 @@ func (s *AuthOIDCScenario) runTailscaleUp( log.Printf("client %s is ready", client.Hostname()) } - namespace.joinWaitGroup.Wait() + user.joinWaitGroup.Wait() return nil } - return fmt.Errorf("failed to up tailscale node: %w", errNoNamespaceAvailable) + return fmt.Errorf("failed to up tailscale node: %w", errNoUserAvailable) } func pingAll(t *testing.T, clients []TailscaleClient, ips []netip.Addr) int { diff --git a/integration/auth_web_flow_test.go b/integration/auth_web_flow_test.go index 4c42dfb..39412e8 100644 --- a/integration/auth_web_flow_test.go +++ b/integration/auth_web_flow_test.go @@ -35,8 +35,8 @@ func TestAuthWebFlowAuthenticationPingAll(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), - "namespace2": len(TailscaleVersions), + "user1": len(TailscaleVersions), + "user2": len(TailscaleVersions), } err = scenario.CreateHeadscaleEnv(spec, hsic.WithTestName("webauthping")) @@ -93,8 +93,8 @@ func TestAuthWebFlowLogoutAndRelogin(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), - "namespace2": len(TailscaleVersions), + "user1": len(TailscaleVersions), + "user2": len(TailscaleVersions), } err = scenario.CreateHeadscaleEnv(spec, hsic.WithTestName("weblogout")) @@ -156,8 +156,8 @@ func TestAuthWebFlowLogoutAndRelogin(t *testing.T) { t.Errorf("failed to get headscale server: %s", err) } - for namespaceName := range spec { - err = scenario.runTailscaleUp(namespaceName, headscale.GetEndpoint()) + for userName := range spec { + err = scenario.runTailscaleUp(userName, headscale.GetEndpoint()) if err != nil { t.Errorf("failed to run tailscale up: %s", err) } @@ -225,7 +225,7 @@ func TestAuthWebFlowLogoutAndRelogin(t *testing.T) { } func (s *AuthWebFlowScenario) CreateHeadscaleEnv( - namespaces map[string]int, + users map[string]int, opts ...hsic.Option, ) error { headscale, err := s.Headscale(opts...) @@ -238,19 +238,19 @@ func (s *AuthWebFlowScenario) CreateHeadscaleEnv( return err } - for namespaceName, clientCount := range namespaces { - log.Printf("creating namespace %s with %d clients", namespaceName, clientCount) - err = s.CreateNamespace(namespaceName) + for userName, clientCount := range users { + log.Printf("creating user %s with %d clients", userName, clientCount) + err = s.CreateUser(userName) if err != nil { return err } - err = s.CreateTailscaleNodesInNamespace(namespaceName, "all", clientCount) + err = s.CreateTailscaleNodesInUser(userName, "all", clientCount) if err != nil { return err } - err = s.runTailscaleUp(namespaceName, headscale.GetEndpoint()) + err = s.runTailscaleUp(userName, headscale.GetEndpoint()) if err != nil { return err } @@ -260,15 +260,15 @@ func (s *AuthWebFlowScenario) CreateHeadscaleEnv( } func (s *AuthWebFlowScenario) runTailscaleUp( - namespaceStr, loginServer string, + userStr, loginServer string, ) error { - log.Printf("running tailscale up for namespace %s", namespaceStr) - if namespace, ok := s.namespaces[namespaceStr]; ok { - for _, client := range namespace.Clients { - namespace.joinWaitGroup.Add(1) + log.Printf("running tailscale up for user %s", userStr) + if user, ok := s.users[userStr]; ok { + for _, client := range user.Clients { + user.joinWaitGroup.Add(1) go func(c TailscaleClient) { - defer namespace.joinWaitGroup.Done() + defer user.joinWaitGroup.Done() // TODO(juanfont): error handle this loginURL, err := c.UpWithLoginURL(loginServer) @@ -276,7 +276,7 @@ func (s *AuthWebFlowScenario) runTailscaleUp( log.Printf("failed to run tailscale up: %s", err) } - err = s.runHeadscaleRegister(namespaceStr, loginURL) + err = s.runHeadscaleRegister(userStr, loginURL) if err != nil { log.Printf("failed to register client: %s", err) } @@ -287,15 +287,15 @@ func (s *AuthWebFlowScenario) runTailscaleUp( log.Printf("error waiting for client %s to be ready: %s", client.Hostname(), err) } } - namespace.joinWaitGroup.Wait() + user.joinWaitGroup.Wait() return nil } - return fmt.Errorf("failed to up tailscale node: %w", errNoNamespaceAvailable) + return fmt.Errorf("failed to up tailscale node: %w", errNoUserAvailable) } -func (s *AuthWebFlowScenario) runHeadscaleRegister(namespaceStr string, loginURL *url.URL) error { +func (s *AuthWebFlowScenario) runHeadscaleRegister(userStr string, loginURL *url.URL) error { headscale, err := s.Headscale() if err != nil { return err @@ -335,7 +335,7 @@ func (s *AuthWebFlowScenario) runHeadscaleRegister(namespaceStr string, loginURL if headscale, err := s.Headscale(); err == nil { _, err = headscale.Execute( - []string{"headscale", "-n", namespaceStr, "nodes", "register", "--key", key}, + []string{"headscale", "-n", userStr, "nodes", "register", "--key", key}, ) if err != nil { log.Printf("failed to register node: %s", err) diff --git a/integration/cli_test.go b/integration/cli_test.go index 1a6442c..4e87691 100644 --- a/integration/cli_test.go +++ b/integration/cli_test.go @@ -28,7 +28,7 @@ func executeAndUnmarshal[T any](headscale ControlServer, command []string, resul return nil } -func TestNamespaceCommand(t *testing.T) { +func TestUserCommand(t *testing.T) { IntegrationSkip(t) t.Parallel() @@ -36,8 +36,8 @@ func TestNamespaceCommand(t *testing.T) { assert.NoError(t, err) spec := map[string]int{ - "namespace1": 0, - "namespace2": 0, + "user1": 0, + "user2": 0, } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins")) @@ -46,60 +46,60 @@ func TestNamespaceCommand(t *testing.T) { headscale, err := scenario.Headscale() assert.NoError(t, err) - var listNamespaces []v1.Namespace + var listUsers []v1.User err = executeAndUnmarshal(headscale, []string{ "headscale", - "namespaces", + "users", "list", "--output", "json", }, - &listNamespaces, + &listUsers, ) assert.NoError(t, err) - result := []string{listNamespaces[0].Name, listNamespaces[1].Name} + result := []string{listUsers[0].Name, listUsers[1].Name} sort.Strings(result) assert.Equal( t, - []string{"namespace1", "namespace2"}, + []string{"user1", "user2"}, result, ) _, err = headscale.Execute( []string{ "headscale", - "namespaces", + "users", "rename", "--output", "json", - "namespace2", + "user2", "newname", }, ) assert.NoError(t, err) - var listAfterRenameNamespaces []v1.Namespace + var listAfterRenameUsers []v1.User err = executeAndUnmarshal(headscale, []string{ "headscale", - "namespaces", + "users", "list", "--output", "json", }, - &listAfterRenameNamespaces, + &listAfterRenameUsers, ) assert.NoError(t, err) - result = []string{listAfterRenameNamespaces[0].Name, listAfterRenameNamespaces[1].Name} + result = []string{listAfterRenameUsers[0].Name, listAfterRenameUsers[1].Name} sort.Strings(result) assert.Equal( t, - []string{"namespace1", "newname"}, + []string{"user1", "newname"}, result, ) @@ -111,14 +111,14 @@ func TestPreAuthKeyCommand(t *testing.T) { IntegrationSkip(t) t.Parallel() - namespace := "preauthkeyspace" + user := "preauthkeyspace" count := 3 scenario, err := NewScenario() assert.NoError(t, err) spec := map[string]int{ - namespace: 0, + user: 0, } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clipak")) @@ -137,8 +137,8 @@ func TestPreAuthKeyCommand(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "create", "--reusable", "--expiration", @@ -163,8 +163,8 @@ func TestPreAuthKeyCommand(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "list", "--output", "json", @@ -216,8 +216,8 @@ func TestPreAuthKeyCommand(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "expire", listedPreAuthKeys[1].Key, }, @@ -230,8 +230,8 @@ func TestPreAuthKeyCommand(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "list", "--output", "json", @@ -252,13 +252,13 @@ func TestPreAuthKeyCommandWithoutExpiry(t *testing.T) { IntegrationSkip(t) t.Parallel() - namespace := "pre-auth-key-without-exp-namespace" + user := "pre-auth-key-without-exp-user" scenario, err := NewScenario() assert.NoError(t, err) spec := map[string]int{ - namespace: 0, + user: 0, } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clipaknaexp")) @@ -273,8 +273,8 @@ func TestPreAuthKeyCommandWithoutExpiry(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "create", "--reusable", "--output", @@ -290,8 +290,8 @@ func TestPreAuthKeyCommandWithoutExpiry(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "list", "--output", "json", @@ -317,13 +317,13 @@ func TestPreAuthKeyCommandReusableEphemeral(t *testing.T) { IntegrationSkip(t) t.Parallel() - namespace := "pre-auth-key-reus-ephm-namespace" + user := "pre-auth-key-reus-ephm-user" scenario, err := NewScenario() assert.NoError(t, err) spec := map[string]int{ - namespace: 0, + user: 0, } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clipakresueeph")) @@ -338,8 +338,8 @@ func TestPreAuthKeyCommandReusableEphemeral(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "create", "--reusable=true", "--output", @@ -355,8 +355,8 @@ func TestPreAuthKeyCommandReusableEphemeral(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "create", "--ephemeral=true", "--output", @@ -375,8 +375,8 @@ func TestPreAuthKeyCommandReusableEphemeral(t *testing.T) { []string{ "headscale", "preauthkeys", - "--namespace", - namespace, + "--user", + user, "list", "--output", "json", @@ -396,13 +396,13 @@ func TestEnablingRoutes(t *testing.T) { IntegrationSkip(t) t.Parallel() - namespace := "enable-routing" + user := "enable-routing" scenario, err := NewScenario() assert.NoError(t, err) spec := map[string]int{ - namespace: 3, + user: 3, } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clienableroute")) diff --git a/integration/control.go b/integration/control.go index a0f76e1..3cc3bcb 100644 --- a/integration/control.go +++ b/integration/control.go @@ -10,9 +10,9 @@ type ControlServer interface { GetHealthEndpoint() string GetEndpoint() string WaitForReady() error - CreateNamespace(namespace string) error - CreateAuthKey(namespace string, reusable bool, ephemeral bool) (*v1.PreAuthKey, error) - ListMachinesInNamespace(namespace string) ([]*v1.Machine, error) + CreateUser(user string) error + CreateAuthKey(user string, reusable bool, ephemeral bool) (*v1.PreAuthKey, error) + ListMachinesInUser(user string) ([]*v1.Machine, error) GetCert() []byte GetHostname() string GetIP() string diff --git a/integration/general_test.go b/integration/general_test.go index 5a4ed95..01f8f14 100644 --- a/integration/general_test.go +++ b/integration/general_test.go @@ -22,8 +22,8 @@ func TestPingAllByIP(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), - "namespace2": len(TailscaleVersions), + "user1": len(TailscaleVersions), + "user2": len(TailscaleVersions), } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("pingallbyip")) @@ -77,8 +77,8 @@ func TestAuthKeyLogoutAndRelogin(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), - "namespace2": len(TailscaleVersions), + "user1": len(TailscaleVersions), + "user2": len(TailscaleVersions), } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("pingallbyip")) @@ -121,15 +121,15 @@ func TestAuthKeyLogoutAndRelogin(t *testing.T) { t.Errorf("failed to get headscale server: %s", err) } - for namespaceName := range spec { - key, err := scenario.CreatePreAuthKey(namespaceName, true, false) + for userName := range spec { + key, err := scenario.CreatePreAuthKey(userName, true, false) if err != nil { - t.Errorf("failed to create pre-auth key for namespace %s: %s", namespaceName, err) + t.Errorf("failed to create pre-auth key for user %s: %s", userName, err) } - err = scenario.RunTailscaleUp(namespaceName, headscale.GetEndpoint(), key.GetKey()) + err = scenario.RunTailscaleUp(userName, headscale.GetEndpoint(), key.GetKey()) if err != nil { - t.Errorf("failed to run tailscale up for namespace %s: %s", namespaceName, err) + t.Errorf("failed to run tailscale up for user %s: %s", userName, err) } } @@ -207,8 +207,8 @@ func TestEphemeral(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions), - "namespace2": len(TailscaleVersions), + "user1": len(TailscaleVersions), + "user2": len(TailscaleVersions), } headscale, err := scenario.Headscale(hsic.WithTestName("ephemeral")) @@ -216,25 +216,25 @@ func TestEphemeral(t *testing.T) { t.Errorf("failed to create headscale environment: %s", err) } - for namespaceName, clientCount := range spec { - err = scenario.CreateNamespace(namespaceName) + for userName, clientCount := range spec { + err = scenario.CreateUser(userName) if err != nil { - t.Errorf("failed to create namespace %s: %s", namespaceName, err) + t.Errorf("failed to create user %s: %s", userName, err) } - err = scenario.CreateTailscaleNodesInNamespace(namespaceName, "all", clientCount, []tsic.Option{}...) + err = scenario.CreateTailscaleNodesInUser(userName, "all", clientCount, []tsic.Option{}...) if err != nil { - t.Errorf("failed to create tailscale nodes in namespace %s: %s", namespaceName, err) + t.Errorf("failed to create tailscale nodes in user %s: %s", userName, err) } - key, err := scenario.CreatePreAuthKey(namespaceName, true, true) + key, err := scenario.CreatePreAuthKey(userName, true, true) if err != nil { - t.Errorf("failed to create pre-auth key for namespace %s: %s", namespaceName, err) + t.Errorf("failed to create pre-auth key for user %s: %s", userName, err) } - err = scenario.RunTailscaleUp(namespaceName, headscale.GetEndpoint(), key.GetKey()) + err = scenario.RunTailscaleUp(userName, headscale.GetEndpoint(), key.GetKey()) if err != nil { - t.Errorf("failed to run tailscale up for namespace %s: %s", namespaceName, err) + t.Errorf("failed to run tailscale up for user %s: %s", userName, err) } } @@ -278,19 +278,19 @@ func TestEphemeral(t *testing.T) { t.Logf("all clients logged out") - for namespaceName := range spec { - machines, err := headscale.ListMachinesInNamespace(namespaceName) + for userName := range spec { + machines, err := headscale.ListMachinesInUser(userName) if err != nil { log.Error(). Err(err). - Str("namespace", namespaceName). - Msg("Error listing machines in namespace") + Str("user", userName). + Msg("Error listing machines in user") return } if len(machines) != 0 { - t.Errorf("expected no machines, got %d in namespace %s", len(machines), namespaceName) + t.Errorf("expected no machines, got %d in user %s", len(machines), userName) } } @@ -311,8 +311,8 @@ func TestPingAllByHostname(t *testing.T) { spec := map[string]int{ // Omit 1.16.2 (-1) because it does not have the FQDN field - "namespace3": len(TailscaleVersions) - 1, - "namespace4": len(TailscaleVersions) - 1, + "user3": len(TailscaleVersions) - 1, + "user4": len(TailscaleVersions) - 1, } err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("pingallbyname")) diff --git a/integration/hsic/hsic.go b/integration/hsic/hsic.go index 9f6391a..1d27d9d 100644 --- a/integration/hsic/hsic.go +++ b/integration/hsic/hsic.go @@ -328,10 +328,10 @@ func (t *HeadscaleInContainer) WaitForReady() error { }) } -func (t *HeadscaleInContainer) CreateNamespace( - namespace string, +func (t *HeadscaleInContainer) CreateUser( + user string, ) error { - command := []string{"headscale", "namespaces", "create", namespace} + command := []string{"headscale", "users", "create", user} _, _, err := dockertestutil.ExecuteCommand( t.container, @@ -346,14 +346,14 @@ func (t *HeadscaleInContainer) CreateNamespace( } func (t *HeadscaleInContainer) CreateAuthKey( - namespace string, + user string, reusable bool, ephemeral bool, ) (*v1.PreAuthKey, error) { command := []string{ "headscale", - "--namespace", - namespace, + "--user", + user, "preauthkeys", "create", "--expiration", @@ -388,10 +388,10 @@ func (t *HeadscaleInContainer) CreateAuthKey( return &preAuthKey, nil } -func (t *HeadscaleInContainer) ListMachinesInNamespace( - namespace string, +func (t *HeadscaleInContainer) ListMachinesInUser( + user string, ) ([]*v1.Machine, error) { - command := []string{"headscale", "--namespace", namespace, "nodes", "list", "--output", "json"} + command := []string{"headscale", "--user", user, "nodes", "list", "--output", "json"} result, _, err := dockertestutil.ExecuteCommand( t.container, diff --git a/integration/scenario.go b/integration/scenario.go index 6679f10..60e60fc 100644 --- a/integration/scenario.go +++ b/integration/scenario.go @@ -25,7 +25,7 @@ const ( var ( errNoHeadscaleAvailable = errors.New("no headscale available") - errNoNamespaceAvailable = errors.New("no namespace available") + errNoUserAvailable = errors.New("no user available") // Tailscale started adding TS2021 support in CapabilityVersion>=28 (v1.24.0), but // proper support in Headscale was only added for CapabilityVersion>=39 clients (v1.30.0). @@ -61,7 +61,7 @@ var ( ) ) -type Namespace struct { +type User struct { Clients map[string]TailscaleClient createWaitGroup sync.WaitGroup @@ -75,7 +75,7 @@ type Scenario struct { // use one. controlServers *xsync.MapOf[string, ControlServer] - namespaces map[string]*Namespace + users map[string]*User pool *dockertest.Pool network *dockertest.Network @@ -116,7 +116,7 @@ func NewScenario() (*Scenario, error) { return &Scenario{ controlServers: xsync.NewMapOf[ControlServer](), - namespaces: make(map[string]*Namespace), + users: make(map[string]*User), pool: pool, network: network, @@ -136,9 +136,9 @@ func (s *Scenario) Shutdown() error { return true }) - for namespaceName, namespace := range s.namespaces { - for _, client := range namespace.Clients { - log.Printf("removing client %s in namespace %s", client.Hostname(), namespaceName) + for userName, user := range s.users { + for _, client := range user.Clients { + log.Printf("removing client %s in user %s", client.Hostname(), userName) err := client.Shutdown() if err != nil { return fmt.Errorf("failed to tear down client: %w", err) @@ -158,13 +158,13 @@ func (s *Scenario) Shutdown() error { return nil } -func (s *Scenario) Namespaces() []string { - namespaces := make([]string, 0) - for namespace := range s.namespaces { - namespaces = append(namespaces, namespace) +func (s *Scenario) Users() []string { + users := make([]string, 0) + for user := range s.users { + users = append(users, user) } - return namespaces + return users } /// Headscale related stuff @@ -194,45 +194,45 @@ func (s *Scenario) Headscale(opts ...hsic.Option) (ControlServer, error) { return headscale, nil } -func (s *Scenario) CreatePreAuthKey(namespace string, reusable bool, ephemeral bool) (*v1.PreAuthKey, error) { +func (s *Scenario) CreatePreAuthKey(user string, reusable bool, ephemeral bool) (*v1.PreAuthKey, error) { if headscale, err := s.Headscale(); err == nil { - key, err := headscale.CreateAuthKey(namespace, reusable, ephemeral) + key, err := headscale.CreateAuthKey(user, reusable, ephemeral) if err != nil { - return nil, fmt.Errorf("failed to create namespace: %w", err) + return nil, fmt.Errorf("failed to create user: %w", err) } return key, nil } - return nil, fmt.Errorf("failed to create namespace: %w", errNoHeadscaleAvailable) + return nil, fmt.Errorf("failed to create user: %w", errNoHeadscaleAvailable) } -func (s *Scenario) CreateNamespace(namespace string) error { +func (s *Scenario) CreateUser(user string) error { if headscale, err := s.Headscale(); err == nil { - err := headscale.CreateNamespace(namespace) + err := headscale.CreateUser(user) if err != nil { - return fmt.Errorf("failed to create namespace: %w", err) + return fmt.Errorf("failed to create user: %w", err) } - s.namespaces[namespace] = &Namespace{ + s.users[user] = &User{ Clients: make(map[string]TailscaleClient), } return nil } - return fmt.Errorf("failed to create namespace: %w", errNoHeadscaleAvailable) + return fmt.Errorf("failed to create user: %w", errNoHeadscaleAvailable) } /// Client related stuff -func (s *Scenario) CreateTailscaleNodesInNamespace( - namespaceStr string, +func (s *Scenario) CreateTailscaleNodesInUser( + userStr string, requestedVersion string, count int, opts ...tsic.Option, ) error { - if namespace, ok := s.namespaces[namespaceStr]; ok { + if user, ok := s.users[userStr]; ok { for i := 0; i < count; i++ { version := requestedVersion if requestedVersion == "all" { @@ -247,7 +247,7 @@ func (s *Scenario) CreateTailscaleNodesInNamespace( cert := headscale.GetCert() hostname := headscale.GetHostname() - namespace.createWaitGroup.Add(1) + user.createWaitGroup.Add(1) opts = append(opts, tsic.WithHeadscaleTLS(cert), @@ -255,7 +255,7 @@ func (s *Scenario) CreateTailscaleNodesInNamespace( ) go func() { - defer namespace.createWaitGroup.Done() + defer user.createWaitGroup.Done() // TODO(kradalby): error handle this tsClient, err := tsic.New( @@ -275,26 +275,26 @@ func (s *Scenario) CreateTailscaleNodesInNamespace( log.Printf("failed to wait for tailscaled: %s", err) } - namespace.Clients[tsClient.Hostname()] = tsClient + user.Clients[tsClient.Hostname()] = tsClient }() } - namespace.createWaitGroup.Wait() + user.createWaitGroup.Wait() return nil } - return fmt.Errorf("failed to add tailscale node: %w", errNoNamespaceAvailable) + return fmt.Errorf("failed to add tailscale node: %w", errNoUserAvailable) } func (s *Scenario) RunTailscaleUp( - namespaceStr, loginServer, authKey string, + userStr, loginServer, authKey string, ) error { - if namespace, ok := s.namespaces[namespaceStr]; ok { - for _, client := range namespace.Clients { - namespace.joinWaitGroup.Add(1) + if user, ok := s.users[userStr]; ok { + for _, client := range user.Clients { + user.joinWaitGroup.Add(1) go func(c TailscaleClient) { - defer namespace.joinWaitGroup.Done() + defer user.joinWaitGroup.Done() // TODO(kradalby): error handle this _ = c.Up(loginServer, authKey) @@ -306,19 +306,19 @@ func (s *Scenario) RunTailscaleUp( } } - namespace.joinWaitGroup.Wait() + user.joinWaitGroup.Wait() return nil } - return fmt.Errorf("failed to up tailscale node: %w", errNoNamespaceAvailable) + return fmt.Errorf("failed to up tailscale node: %w", errNoUserAvailable) } func (s *Scenario) CountTailscale() int { count := 0 - for _, namespace := range s.namespaces { - count += len(namespace.Clients) + for _, user := range s.users { + count += len(user.Clients) } return count @@ -327,18 +327,18 @@ func (s *Scenario) CountTailscale() int { func (s *Scenario) WaitForTailscaleSync() error { tsCount := s.CountTailscale() - for _, namespace := range s.namespaces { - for _, client := range namespace.Clients { - namespace.syncWaitGroup.Add(1) + for _, user := range s.users { + for _, client := range user.Clients { + user.syncWaitGroup.Add(1) go func(c TailscaleClient) { - defer namespace.syncWaitGroup.Done() + defer user.syncWaitGroup.Done() // TODO(kradalby): error handle this _ = c.WaitForPeers(tsCount) }(client) } - namespace.syncWaitGroup.Wait() + user.syncWaitGroup.Wait() } return nil @@ -346,9 +346,9 @@ func (s *Scenario) WaitForTailscaleSync() error { // CreateHeadscaleEnv is a conventient method returning a set up Headcale // test environment with nodes of all versions, joined to the server with X -// namespaces. +// users. func (s *Scenario) CreateHeadscaleEnv( - namespaces map[string]int, + users map[string]int, tsOpts []tsic.Option, opts ...hsic.Option, ) error { @@ -357,23 +357,23 @@ func (s *Scenario) CreateHeadscaleEnv( return err } - for namespaceName, clientCount := range namespaces { - err = s.CreateNamespace(namespaceName) + for userName, clientCount := range users { + err = s.CreateUser(userName) if err != nil { return err } - err = s.CreateTailscaleNodesInNamespace(namespaceName, "all", clientCount, tsOpts...) + err = s.CreateTailscaleNodesInUser(userName, "all", clientCount, tsOpts...) if err != nil { return err } - key, err := s.CreatePreAuthKey(namespaceName, true, false) + key, err := s.CreatePreAuthKey(userName, true, false) if err != nil { return err } - err = s.RunTailscaleUp(namespaceName, headscale.GetEndpoint(), key.GetKey()) + err = s.RunTailscaleUp(userName, headscale.GetEndpoint(), key.GetKey()) if err != nil { return err } @@ -382,9 +382,9 @@ func (s *Scenario) CreateHeadscaleEnv( return nil } -func (s *Scenario) GetIPs(namespace string) ([]netip.Addr, error) { +func (s *Scenario) GetIPs(user string) ([]netip.Addr, error) { var ips []netip.Addr - if ns, ok := s.namespaces[namespace]; ok { + if ns, ok := s.users[user]; ok { for _, client := range ns.Clients { clientIps, err := client.IPs() if err != nil { @@ -396,12 +396,12 @@ func (s *Scenario) GetIPs(namespace string) ([]netip.Addr, error) { return ips, nil } - return ips, fmt.Errorf("failed to get ips: %w", errNoNamespaceAvailable) + return ips, fmt.Errorf("failed to get ips: %w", errNoUserAvailable) } -func (s *Scenario) GetClients(namespace string) ([]TailscaleClient, error) { +func (s *Scenario) GetClients(user string) ([]TailscaleClient, error) { var clients []TailscaleClient - if ns, ok := s.namespaces[namespace]; ok { + if ns, ok := s.users[user]; ok { for _, client := range ns.Clients { clients = append(clients, client) } @@ -409,18 +409,18 @@ func (s *Scenario) GetClients(namespace string) ([]TailscaleClient, error) { return clients, nil } - return clients, fmt.Errorf("failed to get clients: %w", errNoNamespaceAvailable) + return clients, fmt.Errorf("failed to get clients: %w", errNoUserAvailable) } -func (s *Scenario) ListTailscaleClients(namespaces ...string) ([]TailscaleClient, error) { +func (s *Scenario) ListTailscaleClients(users ...string) ([]TailscaleClient, error) { var allClients []TailscaleClient - if len(namespaces) == 0 { - namespaces = s.Namespaces() + if len(users) == 0 { + users = s.Users() } - for _, namespace := range namespaces { - clients, err := s.GetClients(namespace) + for _, user := range users { + clients, err := s.GetClients(user) if err != nil { return nil, err } @@ -431,15 +431,15 @@ func (s *Scenario) ListTailscaleClients(namespaces ...string) ([]TailscaleClient return allClients, nil } -func (s *Scenario) ListTailscaleClientsIPs(namespaces ...string) ([]netip.Addr, error) { +func (s *Scenario) ListTailscaleClientsIPs(users ...string) ([]netip.Addr, error) { var allIps []netip.Addr - if len(namespaces) == 0 { - namespaces = s.Namespaces() + if len(users) == 0 { + users = s.Users() } - for _, namespace := range namespaces { - ips, err := s.GetIPs(namespace) + for _, user := range users { + ips, err := s.GetIPs(user) if err != nil { return nil, err } @@ -450,10 +450,10 @@ func (s *Scenario) ListTailscaleClientsIPs(namespaces ...string) ([]netip.Addr, return allIps, nil } -func (s *Scenario) ListTailscaleClientsFQDNs(namespaces ...string) ([]string, error) { +func (s *Scenario) ListTailscaleClientsFQDNs(users ...string) ([]string, error) { allFQDNs := make([]string, 0) - clients, err := s.ListTailscaleClients(namespaces...) + clients, err := s.ListTailscaleClients(users...) if err != nil { return nil, err } @@ -471,17 +471,17 @@ func (s *Scenario) ListTailscaleClientsFQDNs(namespaces ...string) ([]string, er } func (s *Scenario) WaitForTailscaleLogout() { - for _, namespace := range s.namespaces { - for _, client := range namespace.Clients { - namespace.syncWaitGroup.Add(1) + for _, user := range s.users { + for _, client := range user.Clients { + user.syncWaitGroup.Add(1) go func(c TailscaleClient) { - defer namespace.syncWaitGroup.Done() + defer user.syncWaitGroup.Done() // TODO(kradalby): error handle this _ = c.WaitForLogout() }(client) } - namespace.syncWaitGroup.Wait() + user.syncWaitGroup.Wait() } } diff --git a/integration/scenario_test.go b/integration/scenario_test.go index 97005e5..31f6953 100644 --- a/integration/scenario_test.go +++ b/integration/scenario_test.go @@ -31,7 +31,7 @@ func TestHeadscale(t *testing.T) { var err error - namespace := "test-space" + user := "test-space" scenario, err := NewScenario() if err != nil { @@ -50,19 +50,19 @@ func TestHeadscale(t *testing.T) { } }) - t.Run("create-namespace", func(t *testing.T) { - err := scenario.CreateNamespace(namespace) + t.Run("create-user", func(t *testing.T) { + err := scenario.CreateUser(user) if err != nil { - t.Errorf("failed to create namespace: %s", err) + t.Errorf("failed to create user: %s", err) } - if _, ok := scenario.namespaces[namespace]; !ok { - t.Errorf("namespace is not in scenario") + if _, ok := scenario.users[user]; !ok { + t.Errorf("user is not in scenario") } }) t.Run("create-auth-key", func(t *testing.T) { - _, err := scenario.CreatePreAuthKey(namespace, true, false) + _, err := scenario.CreatePreAuthKey(user, true, false) if err != nil { t.Errorf("failed to create preauthkey: %s", err) } @@ -82,24 +82,24 @@ func TestCreateTailscale(t *testing.T) { IntegrationSkip(t) t.Parallel() - namespace := "only-create-containers" + user := "only-create-containers" scenario, err := NewScenario() if err != nil { t.Errorf("failed to create scenario: %s", err) } - scenario.namespaces[namespace] = &Namespace{ + scenario.users[user] = &User{ Clients: make(map[string]TailscaleClient), } t.Run("create-tailscale", func(t *testing.T) { - err := scenario.CreateTailscaleNodesInNamespace(namespace, "all", 3) + err := scenario.CreateTailscaleNodesInUser(user, "all", 3) if err != nil { t.Errorf("failed to add tailscale nodes: %s", err) } - if clients := len(scenario.namespaces[namespace].Clients); clients != 3 { + if clients := len(scenario.users[user].Clients); clients != 3 { t.Errorf("wrong number of tailscale clients: %d != %d", clients, 3) } @@ -122,7 +122,7 @@ func TestTailscaleNodesJoiningHeadcale(t *testing.T) { var err error - namespace := "join-node-test" + user := "join-node-test" count := 1 @@ -143,30 +143,30 @@ func TestTailscaleNodesJoiningHeadcale(t *testing.T) { } }) - t.Run("create-namespace", func(t *testing.T) { - err := scenario.CreateNamespace(namespace) + t.Run("create-user", func(t *testing.T) { + err := scenario.CreateUser(user) if err != nil { - t.Errorf("failed to create namespace: %s", err) + t.Errorf("failed to create user: %s", err) } - if _, ok := scenario.namespaces[namespace]; !ok { - t.Errorf("namespace is not in scenario") + if _, ok := scenario.users[user]; !ok { + t.Errorf("user is not in scenario") } }) t.Run("create-tailscale", func(t *testing.T) { - err := scenario.CreateTailscaleNodesInNamespace(namespace, "1.30.2", count) + err := scenario.CreateTailscaleNodesInUser(user, "1.30.2", count) if err != nil { t.Errorf("failed to add tailscale nodes: %s", err) } - if clients := len(scenario.namespaces[namespace].Clients); clients != count { + if clients := len(scenario.users[user].Clients); clients != count { t.Errorf("wrong number of tailscale clients: %d != %d", clients, count) } }) t.Run("join-headscale", func(t *testing.T) { - key, err := scenario.CreatePreAuthKey(namespace, true, false) + key, err := scenario.CreatePreAuthKey(user, true, false) if err != nil { t.Errorf("failed to create preauthkey: %s", err) } @@ -177,7 +177,7 @@ func TestTailscaleNodesJoiningHeadcale(t *testing.T) { } err = scenario.RunTailscaleUp( - namespace, + user, headscale.GetEndpoint(), key.GetKey(), ) @@ -187,7 +187,7 @@ func TestTailscaleNodesJoiningHeadcale(t *testing.T) { }) t.Run("get-ips", func(t *testing.T) { - ips, err := scenario.GetIPs(namespace) + ips, err := scenario.GetIPs(user) if err != nil { t.Errorf("failed to get tailscale ips: %s", err) } diff --git a/integration/ssh_test.go b/integration/ssh_test.go index 47c4733..66f9f81 100644 --- a/integration/ssh_test.go +++ b/integration/ssh_test.go @@ -41,7 +41,7 @@ var retry = func(times int, sleepInterval time.Duration, return result, stderr, err } -func TestSSHOneNamespaceAllToAll(t *testing.T) { +func TestSSHOneUserAllToAll(t *testing.T) { IntegrationSkip(t) t.Parallel() @@ -51,7 +51,7 @@ func TestSSHOneNamespaceAllToAll(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions) - 5, + "user1": len(TailscaleVersions) - 5, } err = scenario.CreateHeadscaleEnv(spec, @@ -59,7 +59,7 @@ func TestSSHOneNamespaceAllToAll(t *testing.T) { hsic.WithACLPolicy( &headscale.ACLPolicy{ Groups: map[string][]string{ - "group:integration-test": {"namespace1"}, + "group:integration-test": {"user1"}, }, ACLs: []headscale.ACL{ { @@ -117,7 +117,7 @@ func TestSSHOneNamespaceAllToAll(t *testing.T) { } } -func TestSSHMultipleNamespacesAllToAll(t *testing.T) { +func TestSSHMultipleUsersAllToAll(t *testing.T) { IntegrationSkip(t) t.Parallel() @@ -127,8 +127,8 @@ func TestSSHMultipleNamespacesAllToAll(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions) - 5, - "namespace2": len(TailscaleVersions) - 5, + "user1": len(TailscaleVersions) - 5, + "user2": len(TailscaleVersions) - 5, } err = scenario.CreateHeadscaleEnv(spec, @@ -136,7 +136,7 @@ func TestSSHMultipleNamespacesAllToAll(t *testing.T) { hsic.WithACLPolicy( &headscale.ACLPolicy{ Groups: map[string][]string{ - "group:integration-test": {"namespace1", "namespace2"}, + "group:integration-test": {"user1", "user2"}, }, ACLs: []headscale.ACL{ { @@ -163,12 +163,12 @@ func TestSSHMultipleNamespacesAllToAll(t *testing.T) { t.Errorf("failed to create headscale environment: %s", err) } - nsOneClients, err := scenario.ListTailscaleClients("namespace1") + nsOneClients, err := scenario.ListTailscaleClients("user1") if err != nil { t.Errorf("failed to get clients: %s", err) } - nsTwoClients, err := scenario.ListTailscaleClients("namespace2") + nsTwoClients, err := scenario.ListTailscaleClients("user2") if err != nil { t.Errorf("failed to get clients: %s", err) } @@ -183,7 +183,7 @@ func TestSSHMultipleNamespacesAllToAll(t *testing.T) { t.Errorf("failed to get FQDNs: %s", err) } - testInterNamespaceSSH := func(sourceClients []TailscaleClient, targetClients []TailscaleClient) { + testInterUserSSH := func(sourceClients []TailscaleClient, targetClients []TailscaleClient) { for _, client := range sourceClients { for _, peer := range targetClients { assertSSHHostname(t, client, peer) @@ -191,8 +191,8 @@ func TestSSHMultipleNamespacesAllToAll(t *testing.T) { } } - testInterNamespaceSSH(nsOneClients, nsTwoClients) - testInterNamespaceSSH(nsTwoClients, nsOneClients) + testInterUserSSH(nsOneClients, nsTwoClients) + testInterUserSSH(nsTwoClients, nsOneClients) err = scenario.Shutdown() if err != nil { @@ -210,7 +210,7 @@ func TestSSHNoSSHConfigured(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions) - 5, + "user1": len(TailscaleVersions) - 5, } err = scenario.CreateHeadscaleEnv(spec, @@ -218,7 +218,7 @@ func TestSSHNoSSHConfigured(t *testing.T) { hsic.WithACLPolicy( &headscale.ACLPolicy{ Groups: map[string][]string{ - "group:integration-test": {"namespace1"}, + "group:integration-test": {"user1"}, }, ACLs: []headscale.ACL{ { @@ -280,7 +280,7 @@ func TestSSHIsBlockedInACL(t *testing.T) { } spec := map[string]int{ - "namespace1": len(TailscaleVersions) - 5, + "user1": len(TailscaleVersions) - 5, } err = scenario.CreateHeadscaleEnv(spec, @@ -288,7 +288,7 @@ func TestSSHIsBlockedInACL(t *testing.T) { hsic.WithACLPolicy( &headscale.ACLPolicy{ Groups: map[string][]string{ - "group:integration-test": {"namespace1"}, + "group:integration-test": {"user1"}, }, ACLs: []headscale.ACL{ { @@ -347,7 +347,7 @@ func TestSSHIsBlockedInACL(t *testing.T) { } } -func TestSSNamespaceOnlyIsolation(t *testing.T) { +func TestSSUserOnlyIsolation(t *testing.T) { IntegrationSkip(t) t.Parallel() @@ -357,8 +357,8 @@ func TestSSNamespaceOnlyIsolation(t *testing.T) { } spec := map[string]int{ - "namespaceacl1": len(TailscaleVersions) - 5, - "namespaceacl2": len(TailscaleVersions) - 5, + "useracl1": len(TailscaleVersions) - 5, + "useracl2": len(TailscaleVersions) - 5, } err = scenario.CreateHeadscaleEnv(spec, @@ -366,8 +366,8 @@ func TestSSNamespaceOnlyIsolation(t *testing.T) { hsic.WithACLPolicy( &headscale.ACLPolicy{ Groups: map[string][]string{ - "group:ssh1": {"namespaceacl1"}, - "group:ssh2": {"namespaceacl2"}, + "group:ssh1": {"useracl1"}, + "group:ssh2": {"useracl2"}, }, ACLs: []headscale.ACL{ { @@ -392,7 +392,7 @@ func TestSSNamespaceOnlyIsolation(t *testing.T) { }, }, ), - hsic.WithTestName("sshtwonamespaceaclblock"), + hsic.WithTestName("sshtwouseraclblock"), hsic.WithConfigEnv(map[string]string{ "HEADSCALE_EXPERIMENTAL_FEATURE_SSH": "1", }), @@ -401,12 +401,12 @@ func TestSSNamespaceOnlyIsolation(t *testing.T) { t.Errorf("failed to create headscale environment: %s", err) } - ssh1Clients, err := scenario.ListTailscaleClients("namespaceacl1") + ssh1Clients, err := scenario.ListTailscaleClients("useracl1") if err != nil { t.Errorf("failed to get clients: %s", err) } - ssh2Clients, err := scenario.ListTailscaleClients("namespaceacl2") + ssh2Clients, err := scenario.ListTailscaleClients("useracl2") if err != nil { t.Errorf("failed to get clients: %s", err) } diff --git a/integration_cli_test.go b/integration_cli_test.go index 537bf08..d7dee90 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -138,12 +138,12 @@ func (s *IntegrationCLITestSuite) HandleStats( s.stats = stats } -func (s *IntegrationCLITestSuite) createNamespace(name string) (*v1.Namespace, error) { +func (s *IntegrationCLITestSuite) createUser(name string) (*v1.User, error) { result, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", - "namespaces", + "users", "create", name, "--output", @@ -155,38 +155,38 @@ func (s *IntegrationCLITestSuite) createNamespace(name string) (*v1.Namespace, e return nil, err } - var namespace v1.Namespace - err = json.Unmarshal([]byte(result), &namespace) + var user v1.User + err = json.Unmarshal([]byte(result), &user) if err != nil { return nil, err } - return &namespace, nil + return &user, nil } -func (s *IntegrationCLITestSuite) TestNamespaceCommand() { - names := []string{"namespace1", "otherspace", "tasty"} - namespaces := make([]*v1.Namespace, len(names)) +func (s *IntegrationCLITestSuite) TestUserCommand() { + names := []string{"user1", "otherspace", "tasty"} + users := make([]*v1.User, len(names)) - for index, namespaceName := range names { - namespace, err := s.createNamespace(namespaceName) + for index, userName := range names { + user, err := s.createUser(userName) assert.Nil(s.T(), err) - namespaces[index] = namespace + users[index] = user } - assert.Len(s.T(), namespaces, len(names)) + assert.Len(s.T(), users, len(names)) - assert.Equal(s.T(), names[0], namespaces[0].Name) - assert.Equal(s.T(), names[1], namespaces[1].Name) - assert.Equal(s.T(), names[2], namespaces[2].Name) + assert.Equal(s.T(), names[0], users[0].Name) + assert.Equal(s.T(), names[1], users[1].Name) + assert.Equal(s.T(), names[2], users[2].Name) - // Test list namespaces + // Test list users listResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", - "namespaces", + "users", "list", "--output", "json", @@ -195,20 +195,20 @@ func (s *IntegrationCLITestSuite) TestNamespaceCommand() { ) assert.Nil(s.T(), err) - var listedNamespaces []v1.Namespace - err = json.Unmarshal([]byte(listResult), &listedNamespaces) + var listedUsers []v1.User + err = json.Unmarshal([]byte(listResult), &listedUsers) assert.Nil(s.T(), err) - assert.Equal(s.T(), names[0], listedNamespaces[0].Name) - assert.Equal(s.T(), names[1], listedNamespaces[1].Name) - assert.Equal(s.T(), names[2], listedNamespaces[2].Name) + assert.Equal(s.T(), names[0], listedUsers[0].Name) + assert.Equal(s.T(), names[1], listedUsers[1].Name) + assert.Equal(s.T(), names[2], listedUsers[2].Name) - // Test rename namespace + // Test rename user renameResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", - "namespaces", + "users", "rename", "--output", "json", @@ -219,18 +219,18 @@ func (s *IntegrationCLITestSuite) TestNamespaceCommand() { ) assert.Nil(s.T(), err) - var renamedNamespace v1.Namespace - err = json.Unmarshal([]byte(renameResult), &renamedNamespace) + var renamedUser v1.User + err = json.Unmarshal([]byte(renameResult), &renamedUser) assert.Nil(s.T(), err) - assert.Equal(s.T(), renamedNamespace.Name, "newname") + assert.Equal(s.T(), renamedUser.Name, "newname") - // Test list after rename namespaces + // Test list after rename users listAfterRenameResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", - "namespaces", + "users", "list", "--output", "json", @@ -239,19 +239,19 @@ func (s *IntegrationCLITestSuite) TestNamespaceCommand() { ) assert.Nil(s.T(), err) - var listedAfterRenameNamespaces []v1.Namespace - err = json.Unmarshal([]byte(listAfterRenameResult), &listedAfterRenameNamespaces) + var listedAfterRenameUsers []v1.User + err = json.Unmarshal([]byte(listAfterRenameResult), &listedAfterRenameUsers) assert.Nil(s.T(), err) - assert.Equal(s.T(), names[0], listedAfterRenameNamespaces[0].Name) - assert.Equal(s.T(), names[1], listedAfterRenameNamespaces[1].Name) - assert.Equal(s.T(), "newname", listedAfterRenameNamespaces[2].Name) + assert.Equal(s.T(), names[0], listedAfterRenameUsers[0].Name) + assert.Equal(s.T(), names[1], listedAfterRenameUsers[1].Name) + assert.Equal(s.T(), "newname", listedAfterRenameUsers[2].Name) } func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { count := 5 - namespace, err := s.createNamespace("pre-auth-key-namespace") + user, err := s.createUser("pre-auth-key-user") keys := make([]*v1.PreAuthKey, count) assert.Nil(s.T(), err) @@ -262,8 +262,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "create", "--reusable", "--expiration", @@ -292,8 +292,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "list", "--output", "json", @@ -357,8 +357,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "expire", listedPreAuthKeys[i].Key, }, @@ -373,8 +373,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "list", "--output", "json", @@ -410,7 +410,7 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() { } func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { - namespace, err := s.createNamespace("pre-auth-key-without-exp-namespace") + user, err := s.createUser("pre-auth-key-without-exp-user") assert.Nil(s.T(), err) preAuthResult, _, err := ExecuteCommand( @@ -418,8 +418,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "create", "--reusable", "--output", @@ -439,8 +439,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "list", "--output", "json", @@ -463,7 +463,7 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() { } func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { - namespace, err := s.createNamespace("pre-auth-key-reus-ephm-namespace") + user, err := s.createUser("pre-auth-key-reus-ephm-user") assert.Nil(s.T(), err) preAuthReusableResult, _, err := ExecuteCommand( @@ -471,8 +471,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "create", "--reusable=true", "--output", @@ -494,8 +494,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "create", "--ephemeral=true", "--output", @@ -518,8 +518,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { // []string{ // "headscale", // "preauthkeys", - // "--namespace", - // namespace.Name, + // "--user", + // user.Name, // "create", // "--ephemeral", // "--reusable", @@ -536,8 +536,8 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { []string{ "headscale", "preauthkeys", - "--namespace", - namespace.Name, + "--user", + user.Name, "list", "--output", "json", @@ -554,7 +554,7 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandReusableEphemeral() { } func (s *IntegrationCLITestSuite) TestNodeTagCommand() { - namespace, err := s.createNamespace("machine-namespace") + user, err := s.createUser("machine-user") assert.Nil(s.T(), err) machineKeys := []string{ @@ -573,8 +573,8 @@ func (s *IntegrationCLITestSuite) TestNodeTagCommand() { "create-node", "--name", fmt.Sprintf("machine-%d", index+1), - "--namespace", - namespace.Name, + "--user", + user.Name, "--key", machineKey, "--output", @@ -589,8 +589,8 @@ func (s *IntegrationCLITestSuite) TestNodeTagCommand() { []string{ "headscale", "nodes", - "--namespace", - namespace.Name, + "--user", + user.Name, "register", "--key", machineKey, @@ -683,10 +683,10 @@ func (s *IntegrationCLITestSuite) TestNodeTagCommand() { } func (s *IntegrationCLITestSuite) TestNodeCommand() { - namespace, err := s.createNamespace("machine-namespace") + user, err := s.createUser("machine-user") assert.Nil(s.T(), err) - secondNamespace, err := s.createNamespace("other-namespace") + secondUser, err := s.createUser("other-user") assert.Nil(s.T(), err) // Randomly generated machine keys @@ -709,8 +709,8 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { "create-node", "--name", fmt.Sprintf("machine-%d", index+1), - "--namespace", - namespace.Name, + "--user", + user.Name, "--key", machineKey, "--output", @@ -725,8 +725,8 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { []string{ "headscale", "nodes", - "--namespace", - namespace.Name, + "--user", + user.Name, "register", "--key", machineKey, @@ -778,14 +778,14 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { assert.Equal(s.T(), "machine-4", listAll[3].Name) assert.Equal(s.T(), "machine-5", listAll[4].Name) - otherNamespaceMachineKeys := []string{ + otherUserMachineKeys := []string{ "nodekey:b5b444774186d4217adcec407563a1223929465ee2c68a4da13af0d0185b4f8e", "nodekey:dc721977ac7415aafa87f7d4574cbe07c6b171834a6d37375782bdc1fb6b3584", } - otherNamespaceMachines := make([]*v1.Machine, len(otherNamespaceMachineKeys)) + otherUserMachines := make([]*v1.Machine, len(otherUserMachineKeys)) assert.Nil(s.T(), err) - for index, machineKey := range otherNamespaceMachineKeys { + for index, machineKey := range otherUserMachineKeys { _, _, err := ExecuteCommand( &s.headscale, []string{ @@ -793,9 +793,9 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { "debug", "create-node", "--name", - fmt.Sprintf("otherNamespace-machine-%d", index+1), - "--namespace", - secondNamespace.Name, + fmt.Sprintf("otherUser-machine-%d", index+1), + "--user", + secondUser.Name, "--key", machineKey, "--output", @@ -810,8 +810,8 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { []string{ "headscale", "nodes", - "--namespace", - secondNamespace.Name, + "--user", + secondUser.Name, "register", "--key", machineKey, @@ -826,13 +826,13 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { err = json.Unmarshal([]byte(machineResult), &machine) assert.Nil(s.T(), err) - otherNamespaceMachines[index] = &machine + otherUserMachines[index] = &machine } - assert.Len(s.T(), otherNamespaceMachines, len(otherNamespaceMachineKeys)) + assert.Len(s.T(), otherUserMachines, len(otherUserMachineKeys)) - // Test list all nodes after added otherNamespace - listAllWithotherNamespaceResult, _, err := ExecuteCommand( + // Test list all nodes after added otherUser + listAllWithotherUserResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", @@ -845,31 +845,31 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { ) assert.Nil(s.T(), err) - var listAllWithotherNamespace []v1.Machine + var listAllWithotherUser []v1.Machine err = json.Unmarshal( - []byte(listAllWithotherNamespaceResult), - &listAllWithotherNamespace, + []byte(listAllWithotherUserResult), + &listAllWithotherUser, ) assert.Nil(s.T(), err) - // All nodes, machines + otherNamespace - assert.Len(s.T(), listAllWithotherNamespace, 7) + // All nodes, machines + otherUser + assert.Len(s.T(), listAllWithotherUser, 7) - assert.Equal(s.T(), uint64(6), listAllWithotherNamespace[5].Id) - assert.Equal(s.T(), uint64(7), listAllWithotherNamespace[6].Id) + assert.Equal(s.T(), uint64(6), listAllWithotherUser[5].Id) + assert.Equal(s.T(), uint64(7), listAllWithotherUser[6].Id) - assert.Equal(s.T(), "otherNamespace-machine-1", listAllWithotherNamespace[5].Name) - assert.Equal(s.T(), "otherNamespace-machine-2", listAllWithotherNamespace[6].Name) + assert.Equal(s.T(), "otherUser-machine-1", listAllWithotherUser[5].Name) + assert.Equal(s.T(), "otherUser-machine-2", listAllWithotherUser[6].Name) - // Test list all nodes after added otherNamespace - listOnlyotherNamespaceMachineNamespaceResult, _, err := ExecuteCommand( + // Test list all nodes after added otherUser + listOnlyotherUserMachineUserResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", "nodes", "list", - "--namespace", - secondNamespace.Name, + "--user", + secondUser.Name, "--output", "json", }, @@ -877,27 +877,27 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { ) assert.Nil(s.T(), err) - var listOnlyotherNamespaceMachineNamespace []v1.Machine + var listOnlyotherUserMachineUser []v1.Machine err = json.Unmarshal( - []byte(listOnlyotherNamespaceMachineNamespaceResult), - &listOnlyotherNamespaceMachineNamespace, + []byte(listOnlyotherUserMachineUserResult), + &listOnlyotherUserMachineUser, ) assert.Nil(s.T(), err) - assert.Len(s.T(), listOnlyotherNamespaceMachineNamespace, 2) + assert.Len(s.T(), listOnlyotherUserMachineUser, 2) - assert.Equal(s.T(), uint64(6), listOnlyotherNamespaceMachineNamespace[0].Id) - assert.Equal(s.T(), uint64(7), listOnlyotherNamespaceMachineNamespace[1].Id) + assert.Equal(s.T(), uint64(6), listOnlyotherUserMachineUser[0].Id) + assert.Equal(s.T(), uint64(7), listOnlyotherUserMachineUser[1].Id) assert.Equal( s.T(), - "otherNamespace-machine-1", - listOnlyotherNamespaceMachineNamespace[0].Name, + "otherUser-machine-1", + listOnlyotherUserMachineUser[0].Name, ) assert.Equal( s.T(), - "otherNamespace-machine-2", - listOnlyotherNamespaceMachineNamespace[1].Name, + "otherUser-machine-2", + listOnlyotherUserMachineUser[1].Name, ) // Delete a machines @@ -918,15 +918,15 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { ) assert.Nil(s.T(), err) - // Test: list main namespace after machine is deleted - listOnlyMachineNamespaceAfterDeleteResult, _, err := ExecuteCommand( + // Test: list main user after machine is deleted + listOnlyMachineUserAfterDeleteResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", "nodes", "list", - "--namespace", - namespace.Name, + "--user", + user.Name, "--output", "json", }, @@ -934,18 +934,18 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() { ) assert.Nil(s.T(), err) - var listOnlyMachineNamespaceAfterDelete []v1.Machine + var listOnlyMachineUserAfterDelete []v1.Machine err = json.Unmarshal( - []byte(listOnlyMachineNamespaceAfterDeleteResult), - &listOnlyMachineNamespaceAfterDelete, + []byte(listOnlyMachineUserAfterDeleteResult), + &listOnlyMachineUserAfterDelete, ) assert.Nil(s.T(), err) - assert.Len(s.T(), listOnlyMachineNamespaceAfterDelete, 4) + assert.Len(s.T(), listOnlyMachineUserAfterDelete, 4) } func (s *IntegrationCLITestSuite) TestNodeExpireCommand() { - namespace, err := s.createNamespace("machine-expire-namespace") + user, err := s.createUser("machine-expire-user") assert.Nil(s.T(), err) // Randomly generated machine keys @@ -968,8 +968,8 @@ func (s *IntegrationCLITestSuite) TestNodeExpireCommand() { "create-node", "--name", fmt.Sprintf("machine-%d", index+1), - "--namespace", - namespace.Name, + "--user", + user.Name, "--key", machineKey, "--output", @@ -984,8 +984,8 @@ func (s *IntegrationCLITestSuite) TestNodeExpireCommand() { []string{ "headscale", "nodes", - "--namespace", - namespace.Name, + "--user", + user.Name, "register", "--key", machineKey, @@ -1072,7 +1072,7 @@ func (s *IntegrationCLITestSuite) TestNodeExpireCommand() { } func (s *IntegrationCLITestSuite) TestNodeRenameCommand() { - namespace, err := s.createNamespace("machine-rename-command") + user, err := s.createUser("machine-rename-command") assert.Nil(s.T(), err) // Randomly generated machine keys @@ -1095,8 +1095,8 @@ func (s *IntegrationCLITestSuite) TestNodeRenameCommand() { "create-node", "--name", fmt.Sprintf("machine-%d", index+1), - "--namespace", - namespace.Name, + "--user", + user.Name, "--key", machineKey, "--output", @@ -1111,8 +1111,8 @@ func (s *IntegrationCLITestSuite) TestNodeRenameCommand() { []string{ "headscale", "nodes", - "--namespace", - namespace.Name, + "--user", + user.Name, "register", "--key", machineKey, @@ -1389,9 +1389,9 @@ func (s *IntegrationCLITestSuite) TestApiKeyCommand() { } func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { - oldNamespace, err := s.createNamespace("old-namespace") + oldUser, err := s.createUser("old-user") assert.Nil(s.T(), err) - newNamespace, err := s.createNamespace("new-namespace") + newUser, err := s.createUser("new-user") assert.Nil(s.T(), err) // Randomly generated machine key @@ -1405,8 +1405,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { "create-node", "--name", "nomad-machine", - "--namespace", - oldNamespace.Name, + "--user", + oldUser.Name, "--key", machineKey, "--output", @@ -1421,8 +1421,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { []string{ "headscale", "nodes", - "--namespace", - oldNamespace.Name, + "--user", + oldUser.Name, "register", "--key", machineKey, @@ -1439,7 +1439,7 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { assert.Equal(s.T(), uint64(1), machine.Id) assert.Equal(s.T(), "nomad-machine", machine.Name) - assert.Equal(s.T(), machine.Namespace.Name, oldNamespace.Name) + assert.Equal(s.T(), machine.User.Name, oldUser.Name) machineId := fmt.Sprintf("%d", machine.Id) @@ -1451,8 +1451,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { "move", "--identifier", machineId, - "--namespace", - newNamespace.Name, + "--user", + newUser.Name, "--output", "json", }, @@ -1463,7 +1463,7 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { err = json.Unmarshal([]byte(moveToNewNSResult), &machine) assert.Nil(s.T(), err) - assert.Equal(s.T(), machine.Namespace, newNamespace) + assert.Equal(s.T(), machine.User, newUser) listAllNodesResult, _, err := ExecuteCommand( &s.headscale, @@ -1485,8 +1485,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { assert.Len(s.T(), allNodes, 1) assert.Equal(s.T(), allNodes[0].Id, machine.Id) - assert.Equal(s.T(), allNodes[0].Namespace, machine.Namespace) - assert.Equal(s.T(), allNodes[0].Namespace, newNamespace) + assert.Equal(s.T(), allNodes[0].User, machine.User) + assert.Equal(s.T(), allNodes[0].User, newUser) moveToNonExistingNSResult, _, err := ExecuteCommand( &s.headscale, @@ -1496,8 +1496,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { "move", "--identifier", machineId, - "--namespace", - "non-existing-namespace", + "--user", + "non-existing-user", "--output", "json", }, @@ -1508,9 +1508,9 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { assert.Contains( s.T(), string(moveToNonExistingNSResult), - "Namespace not found", + "User not found", ) - assert.Equal(s.T(), machine.Namespace, newNamespace) + assert.Equal(s.T(), machine.User, newUser) moveToOldNSResult, _, err := ExecuteCommand( &s.headscale, @@ -1520,8 +1520,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { "move", "--identifier", machineId, - "--namespace", - oldNamespace.Name, + "--user", + oldUser.Name, "--output", "json", }, @@ -1532,7 +1532,7 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { err = json.Unmarshal([]byte(moveToOldNSResult), &machine) assert.Nil(s.T(), err) - assert.Equal(s.T(), machine.Namespace, oldNamespace) + assert.Equal(s.T(), machine.User, oldUser) moveToSameNSResult, _, err := ExecuteCommand( &s.headscale, @@ -1542,8 +1542,8 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { "move", "--identifier", machineId, - "--namespace", - oldNamespace.Name, + "--user", + oldUser.Name, "--output", "json", }, @@ -1554,7 +1554,7 @@ func (s *IntegrationCLITestSuite) TestNodeMoveCommand() { err = json.Unmarshal([]byte(moveToSameNSResult), &machine) assert.Nil(s.T(), err) - assert.Equal(s.T(), machine.Namespace, oldNamespace) + assert.Equal(s.T(), machine.User, oldUser) } func (s *IntegrationCLITestSuite) TestLoadConfigFromCommand() { diff --git a/integration_common_test.go b/integration_common_test.go index 36f4b6d..7dc0d17 100644 --- a/integration_common_test.go +++ b/integration_common_test.go @@ -47,7 +47,7 @@ var ( } ) -type TestNamespace struct { +type TestUser struct { count int tailscales map[string]dockertest.Resource } @@ -296,7 +296,7 @@ func getMagicFQDN( hostnames[index] = fmt.Sprintf( "%s.%s.headscale.net", listAll[index].GetGivenName(), - listAll[index].GetNamespace().GetName(), + listAll[index].GetUser().GetName(), ) } diff --git a/integration_embedded_derp_test.go b/integration_embedded_derp_test.go index 5bd6dee..45f622a 100644 --- a/integration_embedded_derp_test.go +++ b/integration_embedded_derp_test.go @@ -26,7 +26,7 @@ import ( const ( headscaleDerpHostname = "headscale-derp" - namespaceName = "derpnamespace" + userName = "derpuser" totalContainers = 3 ) @@ -199,22 +199,22 @@ func (s *IntegrationDERPTestSuite) SetupSuite() { } log.Println("headscale container is ready for embedded DERP tests") - log.Printf("Creating headscale namespace: %s\n", namespaceName) + log.Printf("Creating headscale user: %s\n", userName) result, _, err := ExecuteCommand( &s.headscale, - []string{"headscale", "namespaces", "create", namespaceName}, + []string{"headscale", "users", "create", userName}, []string{}, ) - log.Println("headscale create namespace result: ", result) + log.Println("headscale create user result: ", result) assert.Nil(s.T(), err) - log.Printf("Creating pre auth key for %s\n", namespaceName) + log.Printf("Creating pre auth key for %s\n", userName) preAuthResult, _, err := ExecuteCommand( &s.headscale, []string{ "headscale", - "--namespace", - namespaceName, + "--user", + userName, "preauthkeys", "create", "--reusable", diff --git a/machine.go b/machine.go index 90ddb95..8498590 100644 --- a/machine.go +++ b/machine.go @@ -27,8 +27,8 @@ const ( ) ErrCouldNotConvertMachineInterface = Error("failed to convert machine interface") ErrHostnameTooLong = Error("Hostname too long") - ErrDifferentRegisteredNamespace = Error( - "machine was previously registered with a different namespace", + ErrDifferentRegisteredUser = Error( + "machine was previously registered with a different user", ) MachineGivenNameHashLength = 8 MachineGivenNameTrimSize = 2 @@ -57,8 +57,8 @@ type Machine struct { // GivenName is the name used in all DNS related // parts of headscale. GivenName string `gorm:"type:varchar(63);unique_index"` - NamespaceID uint - Namespace Namespace `gorm:"foreignKey:NamespaceID"` + UserID uint + User User `gorm:"foreignKey:UserID"` RegisterMethod string @@ -192,7 +192,7 @@ func getFilteredByACLPeers( Msg("Finding peers filtered by ACLs") peers := make(map[uint64]Machine) - // Aclfilter peers here. We are itering through machines in all namespaces and search through the computed aclRules + // Aclfilter peers here. We are itering through machines in all users and search through the computed aclRules // for match between rule SrcIPs and DstPorts. If the rule is a match we allow the machine to be viewable. machineIPs := machine.IPAddresses.ToStringSlice() for _, peer := range machines { @@ -270,7 +270,7 @@ func (h *Headscale) ListPeers(machine *Machine) (Machines, error) { Msg("Finding direct peers") machines := Machines{} - if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where("node_key <> ?", + if err := h.db.Preload("AuthKey").Preload("AuthKey.User").Preload("User").Where("node_key <> ?", machine.NodeKey).Find(&machines).Error; err != nil { log.Error().Err(err).Msg("Error accessing db") @@ -292,7 +292,7 @@ func (h *Headscale) getPeers(machine *Machine) (Machines, error) { var err error // If ACLs rules are defined, filter visible host list with the ACLs - // else use the classic namespace scope + // else use the classic user scope if h.aclPolicy != nil { var machines []Machine machines, err = h.ListMachines() @@ -343,7 +343,7 @@ func (h *Headscale) getValidPeers(machine *Machine) (Machines, error) { func (h *Headscale) ListMachines() ([]Machine, error) { machines := []Machine{} - if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Find(&machines).Error; err != nil { + if err := h.db.Preload("AuthKey").Preload("AuthKey.User").Preload("User").Find(&machines).Error; err != nil { return nil, err } @@ -352,16 +352,16 @@ func (h *Headscale) ListMachines() ([]Machine, error) { func (h *Headscale) ListMachinesByGivenName(givenName string) ([]Machine, error) { machines := []Machine{} - if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Find(&machines).Where("given_name = ?", givenName).Error; err != nil { + if err := h.db.Preload("AuthKey").Preload("AuthKey.User").Preload("User").Find(&machines).Where("given_name = ?", givenName).Error; err != nil { return nil, err } return machines, nil } -// GetMachine finds a Machine by name and namespace and returns the Machine struct. -func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) { - machines, err := h.ListMachinesInNamespace(namespace) +// GetMachine finds a Machine by name and user and returns the Machine struct. +func (h *Headscale) GetMachine(user string, name string) (*Machine, error) { + machines, err := h.ListMachinesByUser(user) if err != nil { return nil, err } @@ -375,9 +375,9 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) return nil, ErrMachineNotFound } -// GetMachineByGivenName finds a Machine by given name and namespace and returns the Machine struct. -func (h *Headscale) GetMachineByGivenName(namespace string, givenName string) (*Machine, error) { - machines, err := h.ListMachinesInNamespace(namespace) +// GetMachineByGivenName finds a Machine by given name and user and returns the Machine struct. +func (h *Headscale) GetMachineByGivenName(user string, givenName string) (*Machine, error) { + machines, err := h.ListMachinesByUser(user) if err != nil { return nil, err } @@ -394,7 +394,7 @@ func (h *Headscale) GetMachineByGivenName(namespace string, givenName string) (* // GetMachineByID finds a Machine by ID and returns the Machine struct. func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { m := Machine{} - if result := h.db.Preload("AuthKey").Preload("Namespace").Find(&Machine{ID: id}).First(&m); result.Error != nil { + if result := h.db.Preload("AuthKey").Preload("User").Find(&Machine{ID: id}).First(&m); result.Error != nil { return nil, result.Error } @@ -406,7 +406,7 @@ func (h *Headscale) GetMachineByMachineKey( machineKey key.MachinePublic, ) (*Machine, error) { m := Machine{} - if result := h.db.Preload("AuthKey").Preload("Namespace").First(&m, "machine_key = ?", MachinePublicKeyStripPrefix(machineKey)); result.Error != nil { + if result := h.db.Preload("AuthKey").Preload("User").First(&m, "machine_key = ?", MachinePublicKeyStripPrefix(machineKey)); result.Error != nil { return nil, result.Error } @@ -418,7 +418,7 @@ func (h *Headscale) GetMachineByNodeKey( nodeKey key.NodePublic, ) (*Machine, error) { machine := Machine{} - if result := h.db.Preload("AuthKey").Preload("Namespace").First(&machine, "node_key = ?", + if result := h.db.Preload("AuthKey").Preload("User").First(&machine, "node_key = ?", NodePublicKeyStripPrefix(nodeKey)); result.Error != nil { return nil, result.Error } @@ -431,7 +431,7 @@ func (h *Headscale) GetMachineByAnyKey( machineKey key.MachinePublic, nodeKey key.NodePublic, oldNodeKey key.NodePublic, ) (*Machine, error) { machine := Machine{} - if result := h.db.Preload("AuthKey").Preload("Namespace").First(&machine, "machine_key = ? OR node_key = ? OR node_key = ?", + if result := h.db.Preload("AuthKey").Preload("User").First(&machine, "machine_key = ? OR node_key = ? OR node_key = ?", MachinePublicKeyStripPrefix(machineKey), NodePublicKeyStripPrefix(nodeKey), NodePublicKeyStripPrefix(oldNodeKey)); result.Error != nil { @@ -570,9 +570,9 @@ func (h *Headscale) isOutdated(machine *Machine) bool { return true } - // Get the last update from all headscale namespaces to compare with our nodes + // Get the last update from all headscale users to compare with our nodes // last update. - // TODO(kradalby): Only request updates from namespaces where we can talk to nodes + // TODO(kradalby): Only request updates from users where we can talk to nodes // This would mostly be for a bit of performance, and can be calculated based on // ACLs. lastChange := h.getLastStateChange() @@ -720,7 +720,7 @@ func (h *Headscale) toNode( hostname = fmt.Sprintf( "%s.%s.%s", machine.GivenName, - machine.Namespace.Name, + machine.User.Name, baseDomain, ) if len(hostname) > maxHostnameLength { @@ -744,7 +744,7 @@ func (h *Headscale) toNode( strconv.FormatUint(machine.ID, Base10), ), // in headscale, unlike tailcontrol server, IDs are permanent Name: hostname, - User: tailcfg.UserID(machine.NamespaceID), + User: tailcfg.UserID(machine.UserID), Key: nodeKey, KeyExpiry: keyExpiry, Machine: machineKey, @@ -782,7 +782,7 @@ func (machine *Machine) toProto() *v1.Machine { IpAddresses: machine.IPAddresses.ToStringSlice(), Name: machine.Hostname, GivenName: machine.GivenName, - Namespace: machine.Namespace.toProto(), + User: machine.User.toProto(), ForcedTags: machine.ForcedTags, Online: machine.isOnline(), @@ -837,7 +837,7 @@ func getTags( } var found bool for _, owner := range owners { - if machine.Namespace.Name == owner { + if machine.User.Name == owner { found = true } } @@ -859,7 +859,7 @@ func getTags( func (h *Headscale) RegisterMachineFromAuthCallback( nodeKeyStr string, - namespaceName string, + userName string, machineExpiry *time.Time, registrationMethod string, ) (*Machine, error) { @@ -871,28 +871,28 @@ func (h *Headscale) RegisterMachineFromAuthCallback( log.Debug(). Str("nodeKey", nodeKey.ShortString()). - Str("namespaceName", namespaceName). + Str("userName", userName). Str("registrationMethod", registrationMethod). Str("expiresAt", fmt.Sprintf("%v", machineExpiry)). Msg("Registering machine from API/CLI or auth callback") if machineInterface, ok := h.registrationCache.Get(NodePublicKeyStripPrefix(nodeKey)); ok { if registrationMachine, ok := machineInterface.(Machine); ok { - namespace, err := h.GetNamespace(namespaceName) + user, err := h.GetUser(userName) if err != nil { return nil, fmt.Errorf( - "failed to find namespace in register machine from auth callback, %w", + "failed to find user in register machine from auth callback, %w", err, ) } - // Registration of expired machine with different namespace + // Registration of expired machine with different user if registrationMachine.ID != 0 && - registrationMachine.NamespaceID != namespace.ID { - return nil, ErrDifferentRegisteredNamespace + registrationMachine.UserID != user.ID { + return nil, ErrDifferentRegisteredUser } - registrationMachine.NamespaceID = namespace.ID + registrationMachine.UserID = user.ID registrationMachine.RegisterMethod = registrationMethod if machineExpiry != nil { @@ -923,7 +923,7 @@ func (h *Headscale) RegisterMachine(machine Machine, Str("machine", machine.Hostname). Str("machine_key", machine.MachineKey). Str("node_key", machine.NodeKey). - Str("namespace", machine.Namespace.Name). + Str("user", machine.User.Name). Msg("Registering machine") // If the machine exists and we had already IPs for it, we just save it @@ -939,7 +939,7 @@ func (h *Headscale) RegisterMachine(machine Machine, Str("machine", machine.Hostname). Str("machine_key", machine.MachineKey). Str("node_key", machine.NodeKey). - Str("namespace", machine.Namespace.Name). + Str("user", machine.User.Name). Msg("Machine authorized again") return &machine, nil @@ -1137,7 +1137,7 @@ func (h *Headscale) EnableAutoApprovedRoutes(machine *Machine) error { } for _, approvedAlias := range routeApprovers { - if approvedAlias == machine.Namespace.Name { + if approvedAlias == machine.User.Name { approvedRoutes = append(approvedRoutes, advertisedRoute) } else { approvedIps, err := expandAlias([]Machine{*machine}, *h.aclPolicy, approvedAlias, h.cfg.OIDC.StripEmaildomain) diff --git a/machine_test.go b/machine_test.go index 3e95226..481f3db 100644 --- a/machine_test.go +++ b/machine_test.go @@ -15,10 +15,10 @@ import ( ) func (s *Suite) TestGetMachine(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "testmachine") @@ -30,7 +30,7 @@ func (s *Suite) TestGetMachine(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -41,10 +41,10 @@ func (s *Suite) TestGetMachine(c *check.C) { } func (s *Suite) TestGetMachineByID(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachineByID(0) @@ -56,7 +56,7 @@ func (s *Suite) TestGetMachineByID(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -67,10 +67,10 @@ func (s *Suite) TestGetMachineByID(c *check.C) { } func (s *Suite) TestGetMachineByNodeKey(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachineByID(0) @@ -85,7 +85,7 @@ func (s *Suite) TestGetMachineByNodeKey(c *check.C) { NodeKey: NodePublicKeyStripPrefix(nodeKey.Public()), DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -96,10 +96,10 @@ func (s *Suite) TestGetMachineByNodeKey(c *check.C) { } func (s *Suite) TestGetMachineByAnyNodeKey(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachineByID(0) @@ -116,7 +116,7 @@ func (s *Suite) TestGetMachineByAnyNodeKey(c *check.C) { NodeKey: NodePublicKeyStripPrefix(nodeKey.Public()), DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -127,7 +127,7 @@ func (s *Suite) TestGetMachineByAnyNodeKey(c *check.C) { } func (s *Suite) TestDeleteMachine(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) machine := Machine{ ID: 0, @@ -135,7 +135,7 @@ func (s *Suite) TestDeleteMachine(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(1), } @@ -144,12 +144,12 @@ func (s *Suite) TestDeleteMachine(c *check.C) { err = app.DeleteMachine(&machine) c.Assert(err, check.IsNil) - _, err = app.GetMachine(namespace.Name, "testmachine") + _, err = app.GetMachine(user.Name, "testmachine") c.Assert(err, check.NotNil) } func (s *Suite) TestHardDeleteMachine(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) machine := Machine{ ID: 0, @@ -157,7 +157,7 @@ func (s *Suite) TestHardDeleteMachine(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine3", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(1), } @@ -166,15 +166,15 @@ func (s *Suite) TestHardDeleteMachine(c *check.C) { err = app.HardDeleteMachine(&machine) c.Assert(err, check.IsNil) - _, err = app.GetMachine(namespace.Name, "testmachine3") + _, err = app.GetMachine(user.Name, "testmachine3") c.Assert(err, check.NotNil) } func (s *Suite) TestListPeers(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachineByID(0) @@ -187,7 +187,7 @@ func (s *Suite) TestListPeers(c *check.C) { NodeKey: "bar" + strconv.Itoa(index), DiscoKey: "faa" + strconv.Itoa(index), Hostname: "testmachine" + strconv.Itoa(index), - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -208,18 +208,18 @@ func (s *Suite) TestListPeers(c *check.C) { func (s *Suite) TestGetACLFilteredPeers(c *check.C) { type base struct { - namespace *Namespace + user *User key *PreAuthKey } stor := make([]base, 0) for _, name := range []string{"test", "admin"} { - namespace, err := app.CreateNamespace(name) + user, err := app.CreateUser(name) c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) - stor = append(stor, base{namespace, pak}) + stor = append(stor, base{user, pak}) } _, err := app.GetMachineByID(0) @@ -235,7 +235,7 @@ func (s *Suite) TestGetACLFilteredPeers(c *check.C) { netip.MustParseAddr(fmt.Sprintf("100.64.0.%v", strconv.Itoa(index+1))), }, Hostname: "testmachine" + strconv.Itoa(index), - NamespaceID: stor[index%2].namespace.ID, + UserID: stor[index%2].user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(stor[index%2].key.ID), } @@ -267,11 +267,11 @@ func (s *Suite) TestGetACLFilteredPeers(c *check.C) { c.Assert(err, check.IsNil) adminMachine, err := app.GetMachineByID(1) - c.Logf("Machine(%v), namespace: %v", adminMachine.Hostname, adminMachine.Namespace) + c.Logf("Machine(%v), user: %v", adminMachine.Hostname, adminMachine.User) c.Assert(err, check.IsNil) testMachine, err := app.GetMachineByID(2) - c.Logf("Machine(%v), namespace: %v", testMachine.Hostname, testMachine.Namespace) + c.Logf("Machine(%v), user: %v", testMachine.Hostname, testMachine.User) c.Assert(err, check.IsNil) machines, err := app.ListMachines() @@ -294,10 +294,10 @@ func (s *Suite) TestGetACLFilteredPeers(c *check.C) { } func (s *Suite) TestExpireMachine(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "testmachine") @@ -309,7 +309,7 @@ func (s *Suite) TestExpireMachine(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), Expiry: &time.Time{}, @@ -350,13 +350,13 @@ func (s *Suite) TestSerdeAddressStrignSlice(c *check.C) { } func (s *Suite) TestGenerateGivenName(c *check.C) { - namespace1, err := app.CreateNamespace("namespace-1") + user1, err := app.CreateUser("user-1") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace1.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user1.Name, false, false, nil, nil) c.Assert(err, check.IsNil) - _, err = app.GetMachine("namespace-1", "testmachine") + _, err = app.GetMachine("user-1", "testmachine") c.Assert(err, check.NotNil) machine := &Machine{ @@ -366,38 +366,38 @@ func (s *Suite) TestGenerateGivenName(c *check.C) { DiscoKey: "disco-key-1", Hostname: "hostname-1", GivenName: "hostname-1", - NamespaceID: namespace1.ID, + UserID: user1.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(machine) givenName, err := app.GenerateGivenName("machine-key-2", "hostname-2") - comment := check.Commentf("Same namespace, unique machines, unique hostnames, no conflict") + comment := check.Commentf("Same user, unique machines, unique hostnames, no conflict") c.Assert(err, check.IsNil, comment) c.Assert(givenName, check.Equals, "hostname-2", comment) givenName, err = app.GenerateGivenName("machine-key-1", "hostname-1") - comment = check.Commentf("Same namespace, same machine, same hostname, no conflict") + comment = check.Commentf("Same user, same machine, same hostname, no conflict") c.Assert(err, check.IsNil, comment) c.Assert(givenName, check.Equals, "hostname-1", comment) givenName, err = app.GenerateGivenName("machine-key-2", "hostname-1") - comment = check.Commentf("Same namespace, unique machines, same hostname, conflict") + comment = check.Commentf("Same user, unique machines, same hostname, conflict") c.Assert(err, check.IsNil, comment) c.Assert(givenName, check.Matches, fmt.Sprintf("^hostname-1-[a-z0-9]{%d}$", MachineGivenNameHashLength), comment) givenName, err = app.GenerateGivenName("machine-key-2", "hostname-1") - comment = check.Commentf("Unique namespaces, unique machines, same hostname, conflict") + comment = check.Commentf("Unique users, unique machines, same hostname, conflict") c.Assert(err, check.IsNil, comment) c.Assert(givenName, check.Matches, fmt.Sprintf("^hostname-1-[a-z0-9]{%d}$", MachineGivenNameHashLength), comment) } func (s *Suite) TestSetTags(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "testmachine") @@ -409,7 +409,7 @@ func (s *Suite) TestSetTags(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -457,7 +457,7 @@ func Test_getTags(t *testing.T) { }, }, machine: Machine{ - Namespace: Namespace{ + User: User{ Name: "joe", }, HostInfo: HostInfo{ @@ -478,7 +478,7 @@ func Test_getTags(t *testing.T) { }, }, machine: Machine{ - Namespace: Namespace{ + User: User{ Name: "joe", }, HostInfo: HostInfo{ @@ -499,7 +499,7 @@ func Test_getTags(t *testing.T) { }, }, machine: Machine{ - Namespace: Namespace{ + User: User{ Name: "joe", }, HostInfo: HostInfo{ @@ -524,7 +524,7 @@ func Test_getTags(t *testing.T) { }, }, machine: Machine{ - Namespace: Namespace{ + User: User{ Name: "joe", }, HostInfo: HostInfo{ @@ -541,7 +541,7 @@ func Test_getTags(t *testing.T) { args: args{ aclPolicy: nil, machine: Machine{ - Namespace: Namespace{ + User: User{ Name: "joe", }, HostInfo: HostInfo{ @@ -607,21 +607,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -635,19 +635,19 @@ func Test_getFilteredByACLPeers(t *testing.T) { machine: &Machine{ // current machine ID: 1, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, want: Machines{ { ID: 2, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.2")}, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.3")}, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, }, @@ -660,21 +660,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -688,14 +688,14 @@ func Test_getFilteredByACLPeers(t *testing.T) { machine: &Machine{ // current machine ID: 1, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.1")}, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, want: Machines{ { ID: 2, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.2")}, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, }, }, @@ -708,21 +708,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -736,14 +736,14 @@ func Test_getFilteredByACLPeers(t *testing.T) { machine: &Machine{ // current machine ID: 2, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.2")}, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, }, want: Machines{ { ID: 3, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.3")}, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, }, @@ -756,21 +756,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -786,7 +786,7 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, }, want: Machines{ @@ -795,7 +795,7 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, }, }, @@ -808,21 +808,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -838,7 +838,7 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, }, want: Machines{ @@ -847,14 +847,14 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, }, @@ -867,21 +867,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -895,7 +895,7 @@ func Test_getFilteredByACLPeers(t *testing.T) { machine: &Machine{ // current machine ID: 2, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.2")}, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, }, want: Machines{ @@ -904,12 +904,12 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 3, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.3")}, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, }, @@ -922,21 +922,21 @@ func Test_getFilteredByACLPeers(t *testing.T) { IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.1"), }, - Namespace: Namespace{Name: "joe"}, + User: User{Name: "joe"}, }, { ID: 2, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.2"), }, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, { ID: 3, IPAddresses: MachineAddresses{ netip.MustParseAddr("100.64.0.3"), }, - Namespace: Namespace{Name: "mickael"}, + User: User{Name: "mickael"}, }, }, rules: []tailcfg.FilterRule{ // list of all ACLRules registered @@ -944,7 +944,7 @@ func Test_getFilteredByACLPeers(t *testing.T) { machine: &Machine{ // current machine ID: 2, IPAddresses: MachineAddresses{netip.MustParseAddr("100.64.0.2")}, - Namespace: Namespace{Name: "marc"}, + User: User{Name: "marc"}, }, }, want: Machines{}, @@ -1125,10 +1125,10 @@ func (s *Suite) TestAutoApproveRoutes(c *check.C) { err := app.LoadACLPolicy("./tests/acls/acl_policy_autoapprovers.hujson") c.Assert(err, check.IsNil) - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) nodeKey := key.NewNode() @@ -1144,7 +1144,7 @@ func (s *Suite) TestAutoApproveRoutes(c *check.C) { NodeKey: NodePublicKeyStripPrefix(nodeKey.Public()), DiscoKey: "faa", Hostname: "test", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo{ diff --git a/metrics.go b/metrics.go index f0ce16e..f1f8690 100644 --- a/metrics.go +++ b/metrics.go @@ -8,34 +8,34 @@ import ( const prometheusNamespace = "headscale" var ( - // This is a high cardinality metric (namespace x machines), we might want to make this + // This is a high cardinality metric (user x machines), we might want to make this // configurable/opt-in in the future. lastStateUpdate = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: prometheusNamespace, Name: "last_update_seconds", Help: "Time stamp in unix time when a machine or headscale was updated", - }, []string{"namespace", "machine"}) + }, []string{"user", "machine"}) machineRegistrations = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: prometheusNamespace, Name: "machine_registrations_total", Help: "The total amount of registered machine attempts", - }, []string{"action", "auth", "status", "namespace"}) + }, []string{"action", "auth", "status", "user"}) updateRequestsFromNode = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: prometheusNamespace, Name: "update_request_from_node_total", Help: "The number of updates requested by a node/update function", - }, []string{"namespace", "machine", "state"}) + }, []string{"user", "machine", "state"}) updateRequestsSentToNode = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: prometheusNamespace, Name: "update_request_sent_to_node_total", Help: "The number of calls/messages issued on a specific nodes update channel", - }, []string{"namespace", "machine", "status"}) + }, []string{"user", "machine", "status"}) // TODO(kradalby): This is very debugging, we might want to remove it. updateRequestsReceivedOnChannel = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: prometheusNamespace, Name: "update_request_received_on_channel_total", Help: "The number of update requests received on an update channel", - }, []string{"namespace", "machine"}) + }, []string{"user", "machine"}) ) diff --git a/namespaces.go b/namespaces.go index 87d319c..c32213a 100644 --- a/namespaces.go +++ b/namespaces.go @@ -16,10 +16,10 @@ import ( ) const ( - ErrNamespaceExists = Error("Namespace already exists") - ErrNamespaceNotFound = Error("Namespace not found") - ErrNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found") - ErrInvalidNamespaceName = Error("Invalid namespace name") + ErrUserExists = Error("User already exists") + ErrUserNotFound = Error("User not found") + ErrUserStillHasNodes = Error("User not empty: node(s) found") + ErrInvalidUserName = Error("Invalid user name") ) const ( @@ -27,55 +27,55 @@ const ( labelHostnameLength = 63 ) -var invalidCharsInNamespaceRegex = regexp.MustCompile("[^a-z0-9-.]+") +var invalidCharsInUserRegex = regexp.MustCompile("[^a-z0-9-.]+") -// Namespace is the way Headscale implements the concept of users in Tailscale +// User is the way Headscale implements the concept of users in Tailscale // -// At the end of the day, users in Tailscale are some kind of 'bubbles' or namespaces +// At the end of the day, users in Tailscale are some kind of 'bubbles' or users // that contain our machines. -type Namespace struct { +type User struct { gorm.Model Name string `gorm:"unique"` } -// CreateNamespace creates a new Namespace. Returns error if could not be created -// or another namespace already exists. -func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { +// CreateUser creates a new User. Returns error if could not be created +// or another user already exists. +func (h *Headscale) CreateUser(name string) (*User, error) { err := CheckForFQDNRules(name) if err != nil { return nil, err } - namespace := Namespace{} - if err := h.db.Where("name = ?", name).First(&namespace).Error; err == nil { - return nil, ErrNamespaceExists + user := User{} + if err := h.db.Where("name = ?", name).First(&user).Error; err == nil { + return nil, ErrUserExists } - namespace.Name = name - if err := h.db.Create(&namespace).Error; err != nil { + user.Name = name + if err := h.db.Create(&user).Error; err != nil { log.Error(). - Str("func", "CreateNamespace"). + Str("func", "CreateUser"). Err(err). Msg("Could not create row") return nil, err } - return &namespace, nil + return &user, nil } -// DestroyNamespace destroys a Namespace. Returns error if the Namespace does +// DestroyUser destroys a User. Returns error if the User does // not exist or if there are machines associated with it. -func (h *Headscale) DestroyNamespace(name string) error { - namespace, err := h.GetNamespace(name) +func (h *Headscale) DestroyUser(name string) error { + user, err := h.GetUser(name) if err != nil { - return ErrNamespaceNotFound + return ErrUserNotFound } - machines, err := h.ListMachinesInNamespace(name) + machines, err := h.ListMachinesByUser(name) if err != nil { return err } if len(machines) > 0 { - return ErrNamespaceNotEmptyOfNodes + return ErrUserStillHasNodes } keys, err := h.ListPreAuthKeys(name) @@ -89,18 +89,18 @@ func (h *Headscale) DestroyNamespace(name string) error { } } - if result := h.db.Unscoped().Delete(&namespace); result.Error != nil { + if result := h.db.Unscoped().Delete(&user); result.Error != nil { return result.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 { +// RenameUser renames a User. Returns error if the User does +// not exist or if another User exists with the new name. +func (h *Headscale) RenameUser(oldName, newName string) error { var err error - oldNamespace, err := h.GetNamespace(oldName) + oldUser, err := h.GetUser(oldName) if err != nil { return err } @@ -108,76 +108,76 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { if err != nil { return err } - _, err = h.GetNamespace(newName) + _, err = h.GetUser(newName) if err == nil { - return ErrNamespaceExists + return ErrUserExists } - if !errors.Is(err, ErrNamespaceNotFound) { + if !errors.Is(err, ErrUserNotFound) { return err } - oldNamespace.Name = newName + oldUser.Name = newName - if result := h.db.Save(&oldNamespace); result.Error != nil { + if result := h.db.Save(&oldUser); result.Error != nil { return result.Error } return nil } -// GetNamespace fetches a namespace by name. -func (h *Headscale) GetNamespace(name string) (*Namespace, error) { - namespace := Namespace{} - if result := h.db.First(&namespace, "name = ?", name); errors.Is( +// GetUser fetches a user by name. +func (h *Headscale) GetUser(name string) (*User, error) { + user := User{} + if result := h.db.First(&user, "name = ?", name); errors.Is( result.Error, gorm.ErrRecordNotFound, ) { - return nil, ErrNamespaceNotFound + return nil, ErrUserNotFound } - return &namespace, nil + return &user, nil } -// ListNamespaces gets all the existing namespaces. -func (h *Headscale) ListNamespaces() ([]Namespace, error) { - namespaces := []Namespace{} - if err := h.db.Find(&namespaces).Error; err != nil { +// ListUsers gets all the existing users. +func (h *Headscale) ListUsers() ([]User, error) { + users := []User{} + if err := h.db.Find(&users).Error; err != nil { return nil, err } - return namespaces, nil + return users, nil } -// ListMachinesInNamespace gets all the nodes in a given namespace. -func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { +// ListMachinesByUser gets all the nodes in a given user. +func (h *Headscale) ListMachinesByUser(name string) ([]Machine, error) { err := CheckForFQDNRules(name) if err != nil { return nil, err } - namespace, err := h.GetNamespace(name) + user, err := h.GetUser(name) if err != nil { return nil, err } machines := []Machine{} - if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where(&Machine{NamespaceID: namespace.ID}).Find(&machines).Error; err != nil { + if err := h.db.Preload("AuthKey").Preload("AuthKey.User").Preload("User").Where(&Machine{UserID: user.ID}).Find(&machines).Error; err != nil { return nil, err } return machines, nil } -// SetMachineNamespace assigns a Machine to a namespace. -func (h *Headscale) SetMachineNamespace(machine *Machine, namespaceName string) error { - err := CheckForFQDNRules(namespaceName) +// SetMachineUser assigns a Machine to a user. +func (h *Headscale) SetMachineUser(machine *Machine, username string) error { + err := CheckForFQDNRules(username) if err != nil { return err } - namespace, err := h.GetNamespace(namespaceName) + user, err := h.GetUser(username) if err != nil { return err } - machine.Namespace = *namespace + machine.User = *user if result := h.db.Save(&machine); result.Error != nil { return result.Error } @@ -185,7 +185,7 @@ func (h *Headscale) SetMachineNamespace(machine *Machine, namespaceName string) return nil } -func (n *Namespace) toUser() *tailcfg.User { +func (n *User) toTailscaleUser() *tailcfg.User { user := tailcfg.User{ ID: tailcfg.UserID(n.ID), LoginName: n.Name, @@ -199,7 +199,7 @@ func (n *Namespace) toUser() *tailcfg.User { return &user } -func (n *Namespace) toLogin() *tailcfg.Login { +func (n *User) toTailscaleLogin() *tailcfg.Login { login := tailcfg.Login{ ID: tailcfg.LoginID(n.ID), LoginName: n.Name, @@ -215,24 +215,24 @@ func (h *Headscale) getMapResponseUserProfiles( machine Machine, peers Machines, ) []tailcfg.UserProfile { - namespaceMap := make(map[string]Namespace) - namespaceMap[machine.Namespace.Name] = machine.Namespace + userMap := make(map[string]User) + userMap[machine.User.Name] = machine.User for _, peer := range peers { - namespaceMap[peer.Namespace.Name] = peer.Namespace // not worth checking if already is there + userMap[peer.User.Name] = peer.User // not worth checking if already is there } profiles := []tailcfg.UserProfile{} - for _, namespace := range namespaceMap { - displayName := namespace.Name + for _, user := range userMap { + displayName := user.Name if h.cfg.BaseDomain != "" { - displayName = fmt.Sprintf("%s@%s", namespace.Name, h.cfg.BaseDomain) + displayName = fmt.Sprintf("%s@%s", user.Name, h.cfg.BaseDomain) } profiles = append(profiles, tailcfg.UserProfile{ - ID: tailcfg.UserID(namespace.ID), - LoginName: namespace.Name, + ID: tailcfg.UserID(user.ID), + LoginName: user.Name, DisplayName: displayName, }) } @@ -240,16 +240,16 @@ func (h *Headscale) getMapResponseUserProfiles( return profiles } -func (n *Namespace) toProto() *v1.Namespace { - return &v1.Namespace{ +func (n *User) toProto() *v1.User { + return &v1.User{ Id: strconv.FormatUint(uint64(n.ID), Base10), Name: n.Name, CreatedAt: timestamppb.New(n.CreatedAt), } } -// NormalizeToFQDNRules will replace forbidden chars in namespace -// it can also return an error if the namespace doesn't respect RFC 952 and 1123. +// NormalizeToFQDNRules will replace forbidden chars in user +// it can also return an error if the user doesn't respect RFC 952 and 1123. func NormalizeToFQDNRules(name string, stripEmailDomain bool) (string, error) { name = strings.ToLower(name) name = strings.ReplaceAll(name, "'", "") @@ -259,14 +259,14 @@ func NormalizeToFQDNRules(name string, stripEmailDomain bool) (string, error) { } else { name = strings.ReplaceAll(name, "@", ".") } - name = invalidCharsInNamespaceRegex.ReplaceAllString(name, "-") + name = invalidCharsInUserRegex.ReplaceAllString(name, "-") for _, elt := range strings.Split(name, ".") { if len(elt) > labelHostnameLength { return "", fmt.Errorf( "label %v is more than 63 chars: %w", elt, - ErrInvalidNamespaceName, + ErrInvalidUserName, ) } } @@ -279,21 +279,21 @@ func CheckForFQDNRules(name string) error { return fmt.Errorf( "DNS segment must not be over 63 chars. %v doesn't comply with this rule: %w", name, - ErrInvalidNamespaceName, + ErrInvalidUserName, ) } if strings.ToLower(name) != name { return fmt.Errorf( "DNS segment should be lowercase. %v doesn't comply with this rule: %w", name, - ErrInvalidNamespaceName, + ErrInvalidUserName, ) } - if invalidCharsInNamespaceRegex.MatchString(name) { + if invalidCharsInUserRegex.MatchString(name) { return fmt.Errorf( "DNS segment should only be composed of lowercase ASCII letters numbers, hyphen and dots. %v doesn't comply with theses rules: %w", name, - ErrInvalidNamespaceName, + ErrInvalidUserName, ) } diff --git a/namespaces_test.go b/namespaces_test.go index f88cc8f..7b27b43 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -8,43 +8,43 @@ import ( "gorm.io/gorm" ) -func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) { - namespace, err := app.CreateNamespace("test") +func (s *Suite) TestCreateAndDestroyUser(c *check.C) { + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - c.Assert(namespace.Name, check.Equals, "test") + c.Assert(user.Name, check.Equals, "test") - namespaces, err := app.ListNamespaces() + users, err := app.ListUsers() c.Assert(err, check.IsNil) - c.Assert(len(namespaces), check.Equals, 1) + c.Assert(len(users), check.Equals, 1) - err = app.DestroyNamespace("test") + err = app.DestroyUser("test") c.Assert(err, check.IsNil) - _, err = app.GetNamespace("test") + _, err = app.GetUser("test") c.Assert(err, check.NotNil) } -func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { - err := app.DestroyNamespace("test") - c.Assert(err, check.Equals, ErrNamespaceNotFound) +func (s *Suite) TestDestroyUserErrors(c *check.C) { + err := app.DestroyUser("test") + c.Assert(err, check.Equals, ErrUserNotFound) - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) - err = app.DestroyNamespace("test") + err = app.DestroyUser("test") c.Assert(err, check.IsNil) - result := app.db.Preload("Namespace").First(&pak, "key = ?", pak.Key) - // destroying a namespace also deletes all associated preauthkeys + result := app.db.Preload("User").First(&pak, "key = ?", pak.Key) + // destroying a user also deletes all associated preauthkeys c.Assert(result.Error, check.Equals, gorm.ErrRecordNotFound) - namespace, err = app.CreateNamespace("test") + user, err = app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err = app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err = app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) machine := Machine{ @@ -53,57 +53,57 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) - err = app.DestroyNamespace("test") - c.Assert(err, check.Equals, ErrNamespaceNotEmptyOfNodes) + err = app.DestroyUser("test") + c.Assert(err, check.Equals, ErrUserStillHasNodes) } -func (s *Suite) TestRenameNamespace(c *check.C) { - namespaceTest, err := app.CreateNamespace("test") +func (s *Suite) TestRenameUser(c *check.C) { + userTest, err := app.CreateUser("test") c.Assert(err, check.IsNil) - c.Assert(namespaceTest.Name, check.Equals, "test") + c.Assert(userTest.Name, check.Equals, "test") - namespaces, err := app.ListNamespaces() + users, err := app.ListUsers() c.Assert(err, check.IsNil) - c.Assert(len(namespaces), check.Equals, 1) + c.Assert(len(users), check.Equals, 1) - err = app.RenameNamespace("test", "test-renamed") + err = app.RenameUser("test", "test-renamed") c.Assert(err, check.IsNil) - _, err = app.GetNamespace("test") - c.Assert(err, check.Equals, ErrNamespaceNotFound) + _, err = app.GetUser("test") + c.Assert(err, check.Equals, ErrUserNotFound) - _, err = app.GetNamespace("test-renamed") + _, err = app.GetUser("test-renamed") c.Assert(err, check.IsNil) - err = app.RenameNamespace("test-does-not-exit", "test") - c.Assert(err, check.Equals, ErrNamespaceNotFound) + err = app.RenameUser("test-does-not-exit", "test") + c.Assert(err, check.Equals, ErrUserNotFound) - namespaceTest2, err := app.CreateNamespace("test2") + userTest2, err := app.CreateUser("test2") c.Assert(err, check.IsNil) - c.Assert(namespaceTest2.Name, check.Equals, "test2") + c.Assert(userTest2.Name, check.Equals, "test2") - err = app.RenameNamespace("test2", "test-renamed") - c.Assert(err, check.Equals, ErrNamespaceExists) + err = app.RenameUser("test2", "test-renamed") + c.Assert(err, check.Equals, ErrUserExists) } func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { - namespaceShared1, err := app.CreateNamespace("shared1") + userShared1, err := app.CreateUser("shared1") c.Assert(err, check.IsNil) - namespaceShared2, err := app.CreateNamespace("shared2") + userShared2, err := app.CreateUser("shared2") c.Assert(err, check.IsNil) - namespaceShared3, err := app.CreateNamespace("shared3") + userShared3, err := app.CreateUser("shared3") c.Assert(err, check.IsNil) preAuthKeyShared1, err := app.CreatePreAuthKey( - namespaceShared1.Name, + userShared1.Name, false, false, nil, @@ -112,7 +112,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { c.Assert(err, check.IsNil) preAuthKeyShared2, err := app.CreatePreAuthKey( - namespaceShared2.Name, + userShared2.Name, false, false, nil, @@ -121,7 +121,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { c.Assert(err, check.IsNil) preAuthKeyShared3, err := app.CreatePreAuthKey( - namespaceShared3.Name, + userShared3.Name, false, false, nil, @@ -130,7 +130,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { c.Assert(err, check.IsNil) preAuthKey2Shared1, err := app.CreatePreAuthKey( - namespaceShared1.Name, + userShared1.Name, false, false, nil, @@ -138,7 +138,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { ) c.Assert(err, check.IsNil) - _, err = app.GetMachine(namespaceShared1.Name, "test_get_shared_nodes_1") + _, err = app.GetMachine(userShared1.Name, "test_get_shared_nodes_1") c.Assert(err, check.NotNil) machineInShared1 := &Machine{ @@ -147,15 +147,15 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", Hostname: "test_get_shared_nodes_1", - NamespaceID: namespaceShared1.ID, - Namespace: *namespaceShared1, + UserID: userShared1.ID, + User: *userShared1, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.1")}, AuthKeyID: uint(preAuthKeyShared1.ID), } app.db.Save(machineInShared1) - _, err = app.GetMachine(namespaceShared1.Name, machineInShared1.Hostname) + _, err = app.GetMachine(userShared1.Name, machineInShared1.Hostname) c.Assert(err, check.IsNil) machineInShared2 := &Machine{ @@ -164,15 +164,15 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_2", - NamespaceID: namespaceShared2.ID, - Namespace: *namespaceShared2, + UserID: userShared2.ID, + User: *userShared2, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.2")}, AuthKeyID: uint(preAuthKeyShared2.ID), } app.db.Save(machineInShared2) - _, err = app.GetMachine(namespaceShared2.Name, machineInShared2.Hostname) + _, err = app.GetMachine(userShared2.Name, machineInShared2.Hostname) c.Assert(err, check.IsNil) machineInShared3 := &Machine{ @@ -181,15 +181,15 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_3", - NamespaceID: namespaceShared3.ID, - Namespace: *namespaceShared3, + UserID: userShared3.ID, + User: *userShared3, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.3")}, AuthKeyID: uint(preAuthKeyShared3.ID), } app.db.Save(machineInShared3) - _, err = app.GetMachine(namespaceShared3.Name, machineInShared3.Hostname) + _, err = app.GetMachine(userShared3.Name, machineInShared3.Hostname) c.Assert(err, check.IsNil) machine2InShared1 := &Machine{ @@ -198,8 +198,8 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", Hostname: "test_get_shared_nodes_4", - NamespaceID: namespaceShared1.ID, - Namespace: *namespaceShared1, + UserID: userShared1.ID, + User: *userShared1, RegisterMethod: RegisterMethodAuthKey, IPAddresses: []netip.Addr{netip.MustParseAddr("100.64.0.4")}, AuthKeyID: uint(preAuthKey2Shared1.ID), @@ -218,7 +218,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { found := false for _, userProfiles := range userProfiles { - if userProfiles.DisplayName == namespaceShared1.Name { + if userProfiles.DisplayName == userShared1.Name { found = true break @@ -228,7 +228,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { found = false for _, userProfile := range userProfiles { - if userProfile.DisplayName == namespaceShared2.Name { + if userProfile.DisplayName == userShared2.Name { found = true break @@ -294,7 +294,7 @@ func TestNormalizeToFQDNRules(t *testing.T) { wantErr: false, }, { - name: "namespace name with space", + name: "user name with space", args: args{ name: "name space", stripEmailDomain: false, @@ -303,7 +303,7 @@ func TestNormalizeToFQDNRules(t *testing.T) { wantErr: false, }, { - name: "namespace with quote", + name: "user with quote", args: args{ name: "Jamie's iPhone 5", stripEmailDomain: false, @@ -341,29 +341,29 @@ func TestCheckForFQDNRules(t *testing.T) { wantErr bool }{ { - name: "valid: namespace", - args: args{name: "valid-namespace"}, + name: "valid: user", + args: args{name: "valid-user"}, wantErr: false, }, { - name: "invalid: capitalized namespace", - args: args{name: "Invalid-CapItaLIzed-namespace"}, + name: "invalid: capitalized user", + args: args{name: "Invalid-CapItaLIzed-user"}, wantErr: true, }, { - name: "invalid: email as namespace", + name: "invalid: email as user", args: args{name: "foo.bar@example.com"}, wantErr: true, }, { - name: "invalid: chars in namespace name", - args: args{name: "super-namespace+name"}, + name: "invalid: chars in user name", + args: args{name: "super-user+name"}, wantErr: true, }, { - name: "invalid: too long name for namespace", + name: "invalid: too long name for user", args: args{ - name: "super-long-namespace-name-that-should-be-a-little-more-than-63-chars", + name: "super-long-user-name-that-should-be-a-little-more-than-63-chars", }, wantErr: true, }, @@ -377,14 +377,14 @@ func TestCheckForFQDNRules(t *testing.T) { } } -func (s *Suite) TestSetMachineNamespace(c *check.C) { - oldNamespace, err := app.CreateNamespace("old") +func (s *Suite) TestSetMachineUser(c *check.C) { + oldUser, err := app.CreateUser("old") c.Assert(err, check.IsNil) - newNamespace, err := app.CreateNamespace("new") + newUser, err := app.CreateUser("new") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(oldNamespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(oldUser.Name, false, false, nil, nil) c.Assert(err, check.IsNil) machine := Machine{ @@ -393,23 +393,23 @@ func (s *Suite) TestSetMachineNamespace(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: oldNamespace.ID, + UserID: oldUser.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } app.db.Save(&machine) - c.Assert(machine.NamespaceID, check.Equals, oldNamespace.ID) + c.Assert(machine.UserID, check.Equals, oldUser.ID) - err = app.SetMachineNamespace(&machine, newNamespace.Name) + err = app.SetMachineUser(&machine, newUser.Name) c.Assert(err, check.IsNil) - c.Assert(machine.NamespaceID, check.Equals, newNamespace.ID) - c.Assert(machine.Namespace.Name, check.Equals, newNamespace.Name) + c.Assert(machine.UserID, check.Equals, newUser.ID) + c.Assert(machine.User.Name, check.Equals, newUser.Name) - err = app.SetMachineNamespace(&machine, "non-existing-namespace") - c.Assert(err, check.Equals, ErrNamespaceNotFound) + err = app.SetMachineUser(&machine, "non-existing-user") + c.Assert(err, check.Equals, ErrUserNotFound) - err = app.SetMachineNamespace(&machine, newNamespace.Name) + err = app.SetMachineUser(&machine, newUser.Name) c.Assert(err, check.IsNil) - c.Assert(machine.NamespaceID, check.Equals, newNamespace.ID) - c.Assert(machine.Namespace.Name, check.Equals, newNamespace.Name) + c.Assert(machine.UserID, check.Equals, newUser.ID) + c.Assert(machine.User.Name, check.Equals, newUser.Name) } diff --git a/oidc.go b/oidc.go index e321ef5..4909ba9 100644 --- a/oidc.go +++ b/oidc.go @@ -171,7 +171,7 @@ var oidcCallbackTemplate = template.Must( ) // OIDCCallback handles the callback from the OIDC endpoint -// Retrieves the nkey from the state cache and adds the machine to the users email namespace +// Retrieves the nkey from the state cache and adds the machine to the users email user // TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities // TODO: Add groups information from OIDC tokens into machine HostInfo // Listens in /oidc/callback. @@ -223,7 +223,7 @@ func (h *Headscale) OIDCCallback( return } - namespaceName, err := getNamespaceName(writer, claims, h.cfg.OIDC.StripEmaildomain) + userName, err := getUserName(writer, claims, h.cfg.OIDC.StripEmaildomain) if err != nil { return } @@ -231,12 +231,12 @@ func (h *Headscale) OIDCCallback( // register the machine if it's new log.Debug().Msg("Registering new machine after successful callback") - namespace, err := h.findOrCreateNewNamespaceForOIDCCallback(writer, namespaceName) + user, err := h.findOrCreateNewUserForOIDCCallback(writer, userName) if err != nil { return } - if err := h.registerMachineForOIDCCallback(writer, namespace, nodeKey, idToken.Expiry); err != nil { + if err := h.registerMachineForOIDCCallback(writer, user, nodeKey, idToken.Expiry); err != nil { return } @@ -606,12 +606,12 @@ func (h *Headscale) validateMachineForOIDCCallback( return &nodeKey, false, nil } -func getNamespaceName( +func getUserName( writer http.ResponseWriter, claims *IDTokenClaims, stripEmaildomain bool, ) (string, error) { - namespaceName, err := NormalizeToFQDNRules( + userName, err := NormalizeToFQDNRules( claims.Email, stripEmaildomain, ) @@ -630,25 +630,25 @@ func getNamespaceName( return "", err } - return namespaceName, nil + return userName, nil } -func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( +func (h *Headscale) findOrCreateNewUserForOIDCCallback( writer http.ResponseWriter, - namespaceName string, -) (*Namespace, error) { - namespace, err := h.GetNamespace(namespaceName) - if errors.Is(err, ErrNamespaceNotFound) { - namespace, err = h.CreateNamespace(namespaceName) + userName string, +) (*User, error) { + user, err := h.GetUser(userName) + if errors.Is(err, ErrUserNotFound) { + user, err = h.CreateUser(userName) if err != nil { log.Error(). Err(err). Caller(). - Msgf("could not create new namespace '%s'", namespaceName) + Msgf("could not create new user '%s'", userName) writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.WriteHeader(http.StatusInternalServerError) - _, werr := writer.Write([]byte("could not create namespace")) + _, werr := writer.Write([]byte("could not create user")) if werr != nil { log.Error(). Caller(). @@ -662,11 +662,11 @@ func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( log.Error(). Caller(). Err(err). - Str("namespace", namespaceName). - Msg("could not find or create namespace") + Str("user", userName). + Msg("could not find or create user") writer.Header().Set("Content-Type", "text/plain; charset=utf-8") writer.WriteHeader(http.StatusInternalServerError) - _, werr := writer.Write([]byte("could not find or create namespace")) + _, werr := writer.Write([]byte("could not find or create user")) if werr != nil { log.Error(). Caller(). @@ -677,18 +677,18 @@ func (h *Headscale) findOrCreateNewNamespaceForOIDCCallback( return nil, err } - return namespace, nil + return user, nil } func (h *Headscale) registerMachineForOIDCCallback( writer http.ResponseWriter, - namespace *Namespace, + user *User, nodeKey *key.NodePublic, expiry time.Time, ) error { if _, err := h.RegisterMachineFromAuthCallback( nodeKey.String(), - namespace.Name, + user.Name, &expiry, RegisterMethodOIDC, ); err != nil { diff --git a/preauth_keys.go b/preauth_keys.go index 1037bc8..64e44c4 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -18,16 +18,16 @@ const ( ErrPreAuthKeyNotFound = Error("AuthKey not found") ErrPreAuthKeyExpired = Error("AuthKey expired") ErrSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") - ErrNamespaceMismatch = Error("namespace mismatch") + ErrUserMismatch = Error("user mismatch") ErrPreAuthKeyACLTagInvalid = Error("AuthKey tag is invalid") ) -// PreAuthKey describes a pre-authorization key usable in a particular namespace. +// PreAuthKey describes a pre-authorization key usable in a particular user. type PreAuthKey struct { ID uint64 `gorm:"primary_key"` Key string - NamespaceID uint - Namespace Namespace + UserID uint + User User Reusable bool Ephemeral bool `gorm:"default:false"` Used bool `gorm:"default:false"` @@ -44,15 +44,15 @@ type PreAuthKeyACLTag struct { Tag string } -// CreatePreAuthKey creates a new PreAuthKey in a namespace, and returns it. +// CreatePreAuthKey creates a new PreAuthKey in a user, and returns it. func (h *Headscale) CreatePreAuthKey( - namespaceName string, + userName string, reusable bool, ephemeral bool, expiration *time.Time, aclTags []string, ) (*PreAuthKey, error) { - namespace, err := h.GetNamespace(namespaceName) + user, err := h.GetUser(userName) if err != nil { return nil, err } @@ -71,8 +71,8 @@ func (h *Headscale) CreatePreAuthKey( key := PreAuthKey{ Key: kstr, - NamespaceID: namespace.ID, - Namespace: *namespace, + UserID: user.ID, + User: *user, Reusable: reusable, Ephemeral: ephemeral, CreatedAt: &now, @@ -110,15 +110,15 @@ func (h *Headscale) CreatePreAuthKey( return &key, nil } -// ListPreAuthKeys returns the list of PreAuthKeys for a namespace. -func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) { - namespace, err := h.GetNamespace(namespaceName) +// ListPreAuthKeys returns the list of PreAuthKeys for a user. +func (h *Headscale) ListPreAuthKeys(userName string) ([]PreAuthKey, error) { + user, err := h.GetUser(userName) if err != nil { return nil, err } keys := []PreAuthKey{} - if err := h.db.Preload("Namespace").Preload("ACLTags").Where(&PreAuthKey{NamespaceID: namespace.ID}).Find(&keys).Error; err != nil { + if err := h.db.Preload("User").Preload("ACLTags").Where(&PreAuthKey{UserID: user.ID}).Find(&keys).Error; err != nil { return nil, err } @@ -126,14 +126,14 @@ func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) } // GetPreAuthKey returns a PreAuthKey for a given key. -func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, error) { +func (h *Headscale) GetPreAuthKey(user string, key string) (*PreAuthKey, error) { pak, err := h.checkKeyValidity(key) if err != nil { return nil, err } - if pak.Namespace.Name != namespace { - return nil, ErrNamespaceMismatch + if pak.User.Name != user { + return nil, ErrUserMismatch } return pak, nil @@ -178,7 +178,7 @@ func (h *Headscale) UsePreAuthKey(k *PreAuthKey) error { // If returns no error and a PreAuthKey, it can be used. func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { pak := PreAuthKey{} - if result := h.db.Preload("Namespace").Preload("ACLTags").First(&pak, "key = ?", k); errors.Is( + if result := h.db.Preload("User").Preload("ACLTags").First(&pak, "key = ?", k); errors.Is( result.Error, gorm.ErrRecordNotFound, ) { @@ -217,7 +217,7 @@ func (h *Headscale) generateKey() (string, error) { func (key *PreAuthKey) toProto() *v1.PreAuthKey { protoKey := v1.PreAuthKey{ - Namespace: key.Namespace.Name, + User: key.User.Name, Id: strconv.FormatUint(key.ID, Base10), Key: key.Key, Ephemeral: key.Ephemeral, diff --git a/preauth_keys_test.go b/preauth_keys_test.go index 84977db..5d90b04 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -11,36 +11,36 @@ func (*Suite) TestCreatePreAuthKey(c *check.C) { c.Assert(err, check.NotNil) - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - key, err := app.CreatePreAuthKey(namespace.Name, true, false, nil, nil) + key, err := app.CreatePreAuthKey(user.Name, true, false, nil, nil) c.Assert(err, check.IsNil) // Did we get a valid key? c.Assert(key.Key, check.NotNil) c.Assert(len(key.Key), check.Equals, 48) - // Make sure the Namespace association is populated - c.Assert(key.Namespace.Name, check.Equals, namespace.Name) + // Make sure the User association is populated + c.Assert(key.User.Name, check.Equals, user.Name) _, err = app.ListPreAuthKeys("bogus") c.Assert(err, check.NotNil) - keys, err := app.ListPreAuthKeys(namespace.Name) + keys, err := app.ListPreAuthKeys(user.Name) c.Assert(err, check.IsNil) c.Assert(len(keys), check.Equals, 1) - // Make sure the Namespace association is populated - c.Assert((keys)[0].Namespace.Name, check.Equals, namespace.Name) + // Make sure the User association is populated + c.Assert((keys)[0].User.Name, check.Equals, user.Name) } func (*Suite) TestExpiredPreAuthKey(c *check.C) { - namespace, err := app.CreateNamespace("test2") + user, err := app.CreateUser("test2") c.Assert(err, check.IsNil) now := time.Now() - pak, err := app.CreatePreAuthKey(namespace.Name, true, false, &now, nil) + pak, err := app.CreatePreAuthKey(user.Name, true, false, &now, nil) c.Assert(err, check.IsNil) key, err := app.checkKeyValidity(pak.Key) @@ -55,10 +55,10 @@ func (*Suite) TestPreAuthKeyDoesNotExist(c *check.C) { } func (*Suite) TestValidateKeyOk(c *check.C) { - namespace, err := app.CreateNamespace("test3") + user, err := app.CreateUser("test3") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, true, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, true, false, nil, nil) c.Assert(err, check.IsNil) key, err := app.checkKeyValidity(pak.Key) @@ -67,10 +67,10 @@ func (*Suite) TestValidateKeyOk(c *check.C) { } func (*Suite) TestAlreadyUsedKey(c *check.C) { - namespace, err := app.CreateNamespace("test4") + user, err := app.CreateUser("test4") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) machine := Machine{ @@ -79,7 +79,7 @@ func (*Suite) TestAlreadyUsedKey(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testest", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -91,10 +91,10 @@ func (*Suite) TestAlreadyUsedKey(c *check.C) { } func (*Suite) TestReusableBeingUsedKey(c *check.C) { - namespace, err := app.CreateNamespace("test5") + user, err := app.CreateUser("test5") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, true, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, true, false, nil, nil) c.Assert(err, check.IsNil) machine := Machine{ @@ -103,7 +103,7 @@ func (*Suite) TestReusableBeingUsedKey(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testest", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), } @@ -115,10 +115,10 @@ func (*Suite) TestReusableBeingUsedKey(c *check.C) { } func (*Suite) TestNotReusableNotBeingUsedKey(c *check.C) { - namespace, err := app.CreateNamespace("test6") + user, err := app.CreateUser("test6") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) key, err := app.checkKeyValidity(pak.Key) @@ -127,10 +127,10 @@ func (*Suite) TestNotReusableNotBeingUsedKey(c *check.C) { } func (*Suite) TestEphemeralKey(c *check.C) { - namespace, err := app.CreateNamespace("test7") + user, err := app.CreateUser("test7") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, true, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, true, nil, nil) c.Assert(err, check.IsNil) now := time.Now() @@ -140,7 +140,7 @@ func (*Suite) TestEphemeralKey(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testest", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, LastSeen: &now, AuthKeyID: uint(pak.ID), @@ -162,10 +162,10 @@ func (*Suite) TestEphemeralKey(c *check.C) { } func (*Suite) TestExpirePreauthKey(c *check.C) { - namespace, err := app.CreateNamespace("test3") + user, err := app.CreateUser("test3") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, true, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, true, false, nil, nil) c.Assert(err, check.IsNil) c.Assert(pak.Expiration, check.IsNil) @@ -179,10 +179,10 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { } func (*Suite) TestNotReusableMarkedAsUsed(c *check.C) { - namespace, err := app.CreateNamespace("test6") + user, err := app.CreateUser("test6") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) pak.Used = true app.db.Save(&pak) @@ -192,15 +192,15 @@ func (*Suite) TestNotReusableMarkedAsUsed(c *check.C) { } func (*Suite) TestPreAuthKeyACLTags(c *check.C) { - namespace, err := app.CreateNamespace("test8") + user, err := app.CreateUser("test8") c.Assert(err, check.IsNil) - _, err = app.CreatePreAuthKey(namespace.Name, false, false, nil, []string{"badtag"}) + _, err = app.CreatePreAuthKey(user.Name, false, false, nil, []string{"badtag"}) c.Assert(err, check.NotNil) // Confirm that malformed tags are rejected tags := []string{"tag:test1", "tag:test2"} tagsWithDuplicate := []string{"tag:test1", "tag:test2", "tag:test2"} - _, err = app.CreatePreAuthKey(namespace.Name, false, false, nil, tagsWithDuplicate) + _, err = app.CreatePreAuthKey(user.Name, false, false, nil, tagsWithDuplicate) c.Assert(err, check.IsNil) listedPaks, err := app.ListPreAuthKeys("test8") diff --git a/protocol_common.go b/protocol_common.go index e74104d..bded49c 100644 --- a/protocol_common.go +++ b/protocol_common.go @@ -325,7 +325,7 @@ func (h *Headscale) handleAuthKeyCommon( Err(err). Msg("Cannot encode message") http.Error(writer, "Internal server error", http.StatusInternalServerError) - machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). + machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.User.Name). Inc() return @@ -350,7 +350,7 @@ func (h *Headscale) handleAuthKeyCommon( Msg("Failed authentication via AuthKey") if pak != nil { - machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). + machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.User.Name). Inc() } else { machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", "unknown").Inc() @@ -428,7 +428,7 @@ func (h *Headscale) handleAuthKeyCommon( machineToRegister := Machine{ Hostname: registerRequest.Hostinfo.Hostname, GivenName: givenName, - NamespaceID: pak.Namespace.ID, + UserID: pak.User.ID, MachineKey: MachinePublicKeyStripPrefix(machineKey), RegisterMethod: RegisterMethodAuthKey, Expiry: ®isterRequest.Expiry, @@ -447,7 +447,7 @@ func (h *Headscale) handleAuthKeyCommon( Bool("noise", isNoise). Err(err). Msg("could not register machine") - machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). + machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.User.Name). Inc() http.Error(writer, "Internal server error", http.StatusInternalServerError) @@ -462,7 +462,7 @@ func (h *Headscale) handleAuthKeyCommon( Bool("noise", isNoise). Err(err). Msg("Failed to use pre-auth key") - machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). + machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.User.Name). Inc() http.Error(writer, "Internal server error", http.StatusInternalServerError) @@ -470,10 +470,10 @@ func (h *Headscale) handleAuthKeyCommon( } resp.MachineAuthorized = true - resp.User = *pak.Namespace.toUser() + resp.User = *pak.User.toTailscaleUser() // Provide LoginName when registering with pre-auth key // Otherwise it will need to exec `tailscale up` twice to fetch the *LoginName* - resp.Login = *pak.Namespace.toLogin() + resp.Login = *pak.User.toTailscaleLogin() respBody, err := h.marshalResponse(resp, machineKey, isNoise) if err != nil { @@ -484,13 +484,13 @@ func (h *Headscale) handleAuthKeyCommon( Str("machine", registerRequest.Hostinfo.Hostname). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). + machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.User.Name). Inc() http.Error(writer, "Internal server error", http.StatusInternalServerError) return } - machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "success", pak.Namespace.Name). + machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "success", pak.User.Name). Inc() writer.Header().Set("Content-Type", "application/json; charset=utf-8") writer.WriteHeader(http.StatusOK) @@ -600,7 +600,7 @@ func (h *Headscale) handleMachineLogOutCommon( resp.AuthURL = "" resp.MachineAuthorized = false resp.NodeKeyExpired = true - resp.User = *machine.Namespace.toUser() + resp.User = *machine.User.toTailscaleUser() respBody, err := h.marshalResponse(resp, machineKey, isNoise) if err != nil { log.Error(). @@ -662,8 +662,8 @@ func (h *Headscale) handleMachineValidRegistrationCommon( resp.AuthURL = "" resp.MachineAuthorized = true - resp.User = *machine.Namespace.toUser() - resp.Login = *machine.Namespace.toLogin() + resp.User = *machine.User.toTailscaleUser() + resp.Login = *machine.User.toTailscaleLogin() respBody, err := h.marshalResponse(resp, machineKey, isNoise) if err != nil { @@ -672,13 +672,13 @@ func (h *Headscale) handleMachineValidRegistrationCommon( Bool("noise", isNoise). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("update", "web", "error", machine.Namespace.Name). + machineRegistrations.WithLabelValues("update", "web", "error", machine.User.Name). Inc() http.Error(writer, "Internal server error", http.StatusInternalServerError) return } - machineRegistrations.WithLabelValues("update", "web", "success", machine.Namespace.Name). + machineRegistrations.WithLabelValues("update", "web", "success", machine.User.Name). Inc() writer.Header().Set("Content-Type", "application/json; charset=utf-8") @@ -726,7 +726,7 @@ func (h *Headscale) handleMachineRefreshKeyCommon( } resp.AuthURL = "" - resp.User = *machine.Namespace.toUser() + resp.User = *machine.User.toTailscaleUser() respBody, err := h.marshalResponse(resp, machineKey, isNoise) if err != nil { log.Error(). @@ -801,13 +801,13 @@ func (h *Headscale) handleMachineExpiredOrLoggedOutCommon( Bool("noise", isNoise). Err(err). Msg("Cannot encode message") - machineRegistrations.WithLabelValues("reauth", "web", "error", machine.Namespace.Name). + machineRegistrations.WithLabelValues("reauth", "web", "error", machine.User.Name). Inc() http.Error(writer, "Internal server error", http.StatusInternalServerError) return } - machineRegistrations.WithLabelValues("reauth", "web", "success", machine.Namespace.Name). + machineRegistrations.WithLabelValues("reauth", "web", "success", machine.User.Name). Inc() writer.Header().Set("Content-Type", "application/json; charset=utf-8") diff --git a/protocol_common_poll.go b/protocol_common_poll.go index ee04022..09df630 100644 --- a/protocol_common_poll.go +++ b/protocol_common_poll.go @@ -183,7 +183,7 @@ func (h *Headscale) handlePollCommon( } // It sounds like we should update the nodes when we have received a endpoint update // even tho the comments in the tailscale code dont explicitly say so. - updateRequestsFromNode.WithLabelValues(machine.Namespace.Name, machine.Hostname, "endpoint-update"). + updateRequestsFromNode.WithLabelValues(machine.User.Name, machine.Hostname, "endpoint-update"). Inc() updateChan <- struct{}{} @@ -216,7 +216,7 @@ func (h *Headscale) handlePollCommon( Bool("noise", isNoise). Str("machine", machine.Hostname). Msg("Notifying peers") - updateRequestsFromNode.WithLabelValues(machine.Namespace.Name, machine.Hostname, "full-update"). + updateRequestsFromNode.WithLabelValues(machine.User.Name, machine.Hostname, "full-update"). Inc() updateChan <- struct{}{} @@ -342,7 +342,7 @@ func (h *Headscale) pollNetMapStream( now := time.Now().UTC() machine.LastSeen = &now - lastStateUpdate.WithLabelValues(machine.Namespace.Name, machine.Hostname). + lastStateUpdate.WithLabelValues(machine.User.Name, machine.Hostname). Set(float64(now.Unix())) machine.LastSuccessfulUpdate = &now @@ -453,7 +453,7 @@ func (h *Headscale) pollNetMapStream( Str("machine", machine.Hostname). Str("channel", "update"). Msg("Received a request for update") - updateRequestsReceivedOnChannel.WithLabelValues(machine.Namespace.Name, machine.Hostname). + updateRequestsReceivedOnChannel.WithLabelValues(machine.User.Name, machine.Hostname). Inc() if h.isOutdated(machine) { @@ -466,7 +466,7 @@ func (h *Headscale) pollNetMapStream( Bool("noise", isNoise). Str("machine", machine.Hostname). Time("last_successful_update", lastUpdate). - Time("last_state_change", h.getLastStateChange(machine.Namespace)). + Time("last_state_change", h.getLastStateChange(machine.User)). Msgf("There has been updates since the last successful update to %s", machine.Hostname) data, err := h.getMapResponseData(mapRequest, machine, isNoise) if err != nil { @@ -489,7 +489,7 @@ func (h *Headscale) pollNetMapStream( Str("channel", "update"). Err(err). Msg("Could not write the map response") - updateRequestsSentToNode.WithLabelValues(machine.Namespace.Name, machine.Hostname, "failed"). + updateRequestsSentToNode.WithLabelValues(machine.User.Name, machine.Hostname, "failed"). Inc() return @@ -514,7 +514,7 @@ func (h *Headscale) pollNetMapStream( Str("machine", machine.Hostname). Str("channel", "update"). Msg("Updated Map has been sent") - updateRequestsSentToNode.WithLabelValues(machine.Namespace.Name, machine.Hostname, "success"). + updateRequestsSentToNode.WithLabelValues(machine.User.Name, machine.Hostname, "success"). Inc() // Keep track of the last successful update, @@ -540,7 +540,7 @@ func (h *Headscale) pollNetMapStream( } now := time.Now().UTC() - lastStateUpdate.WithLabelValues(machine.Namespace.Name, machine.Hostname). + lastStateUpdate.WithLabelValues(machine.User.Name, machine.Hostname). Set(float64(now.Unix())) machine.LastSuccessfulUpdate = &now @@ -566,7 +566,7 @@ func (h *Headscale) pollNetMapStream( Bool("noise", isNoise). Str("machine", machine.Hostname). Time("last_successful_update", lastUpdate). - Time("last_state_change", h.getLastStateChange(machine.Namespace)). + Time("last_state_change", h.getLastStateChange(machine.User)). Msgf("%s is up to date", machine.Hostname) } @@ -676,7 +676,7 @@ func (h *Headscale) scheduledPollWorker( Str("machine", machine.Hostname). Bool("noise", isNoise). Msg("Sending update request") - updateRequestsFromNode.WithLabelValues(machine.Namespace.Name, machine.Hostname, "scheduled-update"). + updateRequestsFromNode.WithLabelValues(machine.User.Name, machine.Hostname, "scheduled-update"). Inc() select { case updateChan <- struct{}{}: diff --git a/routes_test.go b/routes_test.go index 30ce87c..7af3f05 100644 --- a/routes_test.go +++ b/routes_test.go @@ -10,10 +10,10 @@ import ( ) func (s *Suite) TestGetRoutes(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "test_get_route_machine") @@ -32,7 +32,7 @@ func (s *Suite) TestGetRoutes(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "test_get_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -54,10 +54,10 @@ func (s *Suite) TestGetRoutes(c *check.C) { } func (s *Suite) TestGetEnableRoutes(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "test_enable_route_machine") @@ -83,7 +83,7 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "test_enable_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo), @@ -129,10 +129,10 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) { } func (s *Suite) TestIsUniquePrefix(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "test_enable_route_machine") @@ -157,7 +157,7 @@ func (s *Suite) TestIsUniquePrefix(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "test_enable_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo1), @@ -182,7 +182,7 @@ func (s *Suite) TestIsUniquePrefix(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "test_enable_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo2), @@ -213,10 +213,10 @@ func (s *Suite) TestIsUniquePrefix(c *check.C) { } func (s *Suite) TestSubnetFailover(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "test_enable_route_machine") @@ -243,7 +243,7 @@ func (s *Suite) TestSubnetFailover(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "test_enable_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo1), @@ -280,7 +280,7 @@ func (s *Suite) TestSubnetFailover(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "test_enable_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo2), @@ -358,10 +358,10 @@ func (s *Suite) TestSubnetFailover(c *check.C) { // including both the primary routes the node is responsible for, and the // exit node routes if enabled. func (s *Suite) TestAllowedIPRoutes(c *check.C) { - namespace, err := app.CreateNamespace("test") + user, err := app.CreateUser("test") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "test_enable_route_machine") @@ -402,7 +402,7 @@ func (s *Suite) TestAllowedIPRoutes(c *check.C) { NodeKey: NodePublicKeyStripPrefix(nodeKey.Public()), DiscoKey: DiscoPublicKeyStripPrefix(discoKey.Public()), Hostname: "test_enable_route_machine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), HostInfo: HostInfo(hostInfo1), diff --git a/utils_test.go b/utils_test.go index e442bf6..85495a5 100644 --- a/utils_test.go +++ b/utils_test.go @@ -22,10 +22,10 @@ func (s *Suite) TestGetUsedIps(c *check.C) { ips, err := app.getAvailableIPs() c.Assert(err, check.IsNil) - namespace, err := app.CreateNamespace("test-ip") + user, err := app.CreateUser("test-ip") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "testmachine") @@ -37,7 +37,7 @@ func (s *Suite) TestGetUsedIps(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), IPAddresses: ips, @@ -64,7 +64,7 @@ func (s *Suite) TestGetUsedIps(c *check.C) { } func (s *Suite) TestGetMultiIp(c *check.C) { - namespace, err := app.CreateNamespace("test-ip-multi") + user, err := app.CreateUser("test-ip-multi") c.Assert(err, check.IsNil) for index := 1; index <= 350; index++ { @@ -73,7 +73,7 @@ func (s *Suite) TestGetMultiIp(c *check.C) { ips, err := app.getAvailableIPs() c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "testmachine") @@ -85,7 +85,7 @@ func (s *Suite) TestGetMultiIp(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), IPAddresses: ips, @@ -160,10 +160,10 @@ func (s *Suite) TestGetAvailableIpMachineWithoutIP(c *check.C) { c.Assert(len(ips), check.Equals, 1) c.Assert(ips[0].String(), check.Equals, expected.String()) - namespace, err := app.CreateNamespace("test-ip") + user, err := app.CreateUser("test-ip") c.Assert(err, check.IsNil) - pak, err := app.CreatePreAuthKey(namespace.Name, false, false, nil, nil) + pak, err := app.CreatePreAuthKey(user.Name, false, false, nil, nil) c.Assert(err, check.IsNil) _, err = app.GetMachine("test", "testmachine") @@ -175,7 +175,7 @@ func (s *Suite) TestGetAvailableIpMachineWithoutIP(c *check.C) { NodeKey: "bar", DiscoKey: "faa", Hostname: "testmachine", - NamespaceID: namespace.ID, + UserID: user.ID, RegisterMethod: RegisterMethodAuthKey, AuthKeyID: uint(pak.ID), }