forked from juanfont/headscale
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
policy manager
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Showing
9 changed files
with
455 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package policyv2 | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/juanfont/headscale/hscontrol/types" | ||
"tailscale.com/tailcfg" | ||
) | ||
|
||
type PolicyManager struct { | ||
mu sync.Mutex | ||
pol *Policy | ||
users []types.User | ||
nodes types.Nodes | ||
|
||
filter []tailcfg.FilterRule | ||
|
||
// TODO(kradalby): Implement SSH policy | ||
sshPolicy *tailcfg.SSHPolicy | ||
} | ||
|
||
// NewPolicyManager creates a new PolicyManager from a policy file and a list of users and nodes. | ||
// It returns an error if the policy file is invalid. | ||
// The policy manager will update the filter rules based on the users and nodes. | ||
func NewPolicyManager(b []byte, users []types.User, nodes types.Nodes) (*PolicyManager, error) { | ||
policy, err := policyFromBytes(b) | ||
if err != nil { | ||
return nil, fmt.Errorf("parsing policy: %w", err) | ||
} | ||
|
||
pm := PolicyManager{ | ||
pol: policy, | ||
users: users, | ||
nodes: nodes, | ||
} | ||
|
||
err = pm.updateLocked() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &pm, nil | ||
} | ||
|
||
// Filter returns the current filter rules for the entire tailnet. | ||
func (pm *PolicyManager) Filter() []tailcfg.FilterRule { | ||
pm.mu.Lock() | ||
defer pm.mu.Unlock() | ||
return pm.filter | ||
} | ||
|
||
// updateLocked updates the filter rules based on the current policy and nodes. | ||
// It must be called with the lock held. | ||
func (pm *PolicyManager) updateLocked() error { | ||
filter, err := pm.pol.CompileFilterRules(pm.users, pm.nodes) | ||
if err != nil { | ||
return fmt.Errorf("compiling filter rules: %w", err) | ||
} | ||
|
||
pm.filter = filter | ||
|
||
return nil | ||
} | ||
|
||
// SetUsers updates the users in the policy manager and updates the filter rules. | ||
func (pm *PolicyManager) SetUsers(users []types.User) error { | ||
pm.mu.Lock() | ||
defer pm.mu.Unlock() | ||
pm.users = users | ||
return pm.updateLocked() | ||
} | ||
|
||
// SetNodes updates the nodes in the policy manager and updates the filter rules. | ||
func (pm *PolicyManager) SetNodes(nodes types.Nodes) error { | ||
pm.mu.Lock() | ||
defer pm.mu.Unlock() | ||
pm.nodes = nodes | ||
return pm.updateLocked() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package policyv2 | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/juanfont/headscale/hscontrol/types" | ||
"github.com/stretchr/testify/require" | ||
"gorm.io/gorm" | ||
"tailscale.com/tailcfg" | ||
) | ||
|
||
func node(name, ipv4, ipv6 string, user types.User, hostinfo *tailcfg.Hostinfo) *types.Node { | ||
return &types.Node{ | ||
ID: 0, | ||
Hostname: name, | ||
IPv4: ap(ipv4), | ||
IPv6: ap(ipv6), | ||
User: user, | ||
UserID: user.ID, | ||
Hostinfo: hostinfo, | ||
} | ||
} | ||
|
||
func TestPolicyManager(t *testing.T) { | ||
users := types.Users{ | ||
{Model: gorm.Model{ID: 1}, Name: "testuser", Email: "testuser@headscale.net"}, | ||
{Model: gorm.Model{ID: 2}, Name: "otheruser", Email: "otheruser@headscale.net"}, | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
pol string | ||
nodes types.Nodes | ||
wantFilter []tailcfg.FilterRule | ||
}{ | ||
{ | ||
name: "empty-policy", | ||
pol: "{}", | ||
nodes: types.Nodes{}, | ||
wantFilter: nil, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
pm, err := NewPolicyManager([]byte(tt.pol), users, tt.nodes) | ||
require.NoError(t, err) | ||
|
||
filter := pm.Filter() | ||
if diff := cmp.Diff(filter, tt.wantFilter); diff != "" { | ||
t.Errorf("Filter() mismatch (-want +got):\n%s", diff) | ||
} | ||
|
||
// TODO(kradalby): Test SSH Policy | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters