headscale/acls_types.go

78 lines
1.7 KiB
Go
Raw Normal View History

2021-07-03 09:55:32 +00:00
package headscale
import (
2021-11-05 07:24:00 +00:00
"encoding/json"
2021-07-03 09:55:32 +00:00
"strings"
2021-07-03 15:31:32 +00:00
"github.com/tailscale/hujson"
2021-07-03 09:55:32 +00:00
"inet.af/netaddr"
)
2021-07-04 11:33:00 +00:00
// ACLPolicy represents a Tailscale ACL Policy
2021-07-03 09:55:32 +00:00
type ACLPolicy struct {
Groups Groups `json:"Groups"`
Hosts Hosts `json:"Hosts"`
TagOwners TagOwners `json:"TagOwners"`
ACLs []ACL `json:"ACLs"`
Tests []ACLTest `json:"Tests"`
}
2021-07-04 11:33:00 +00:00
// ACL is a basic rule for the ACL Policy
2021-07-03 09:55:32 +00:00
type ACL struct {
Action string `json:"Action"`
Users []string `json:"Users"`
Ports []string `json:"Ports"`
}
2021-07-04 11:33:00 +00:00
// Groups references a series of alias in the ACL rules
2021-07-03 09:55:32 +00:00
type Groups map[string][]string
2021-07-04 11:33:00 +00:00
// Hosts are alias for IP addresses or subnets
2021-07-03 15:31:32 +00:00
type Hosts map[string]netaddr.IPPrefix
2021-07-03 09:55:32 +00:00
2021-07-04 11:33:00 +00:00
// TagOwners specify what users (namespaces?) are allow to use certain tags
2021-07-03 15:31:32 +00:00
type TagOwners map[string][]string
2021-07-03 09:55:32 +00:00
2021-07-04 11:33:00 +00:00
// ACLTest is not implemented, but should be use to check if a certain rule is allowed
2021-07-03 09:55:32 +00:00
type ACLTest struct {
User string `json:"User"`
Allow []string `json:"Allow"`
Deny []string `json:"Deny,omitempty"`
}
2021-07-04 11:33:00 +00:00
// UnmarshalJSON allows to parse the Hosts directly into netaddr objects
2021-07-03 15:31:32 +00:00
func (h *Hosts) UnmarshalJSON(data []byte) error {
hosts := Hosts{}
hs := make(map[string]string)
2021-11-05 07:24:00 +00:00
ast, err := hujson.Parse(data)
if err != nil {
return err
}
ast.Standardize()
data = ast.Pack()
err = json.Unmarshal(data, &hs)
2021-07-03 15:31:32 +00:00
if err != nil {
return err
2021-07-03 09:55:32 +00:00
}
2021-07-03 15:31:32 +00:00
for k, v := range hs {
2021-07-03 09:55:32 +00:00
if !strings.Contains(v, "/") {
v = v + "/32"
}
prefix, err := netaddr.ParseIPPrefix(v)
if err != nil {
2021-07-03 15:31:32 +00:00
return err
2021-07-03 09:55:32 +00:00
}
hosts[k] = prefix
}
2021-07-03 15:31:32 +00:00
*h = hosts
return nil
}
// IsZero is perhaps a bit naive here
func (p ACLPolicy) IsZero() bool {
if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 {
return true
}
return false
2021-07-03 09:55:32 +00:00
}