Alexey Palazhchenko 06209bba28 chore: update RBAC rules, remove old APIs
Refs #3421.

Signed-off-by: Alexey Palazhchenko <alexey.palazhchenko@gmail.com>
2021-06-18 09:54:49 -07:00

120 lines
2.7 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package role
import (
"sort"
"strings"
)
// Role represents Talos user role.
// Its string value is used everywhere: as the the Organization value of Talos client certificate,
// as the value of talosctl flag, etc.
type Role string
const (
// Prefix for all built-in roles.
Prefix = string("os:")
// Admin defines Talos role for admins.
Admin = Role(Prefix + "admin")
// Reader defines Talos role for readers who can access read-only APIs that do not expose secrets.
Reader = Role(Prefix + "reader")
// EtcdBackup defines Talos role that allows making etcd backups.
EtcdBackup = Role(Prefix + "etcd:backup")
// Impersonator defines Talos role for impersonating another user (and their role).
// Used internally, but may also be granted to the user.
Impersonator = Role(Prefix + "impersonator")
)
// Set represents a set of roles.
type Set struct {
roles map[Role]struct{}
}
var (
// All roles that can be granted to users.
All = MakeSet(Admin, Reader, EtcdBackup, Impersonator)
// Zero is an empty set of roles.
Zero = MakeSet()
)
// MakeSet makes a set of roles from constants.
// Use Parse in other cases.
func MakeSet(roles ...Role) Set {
res := Set{
roles: make(map[Role]struct{}, len(roles)),
}
for _, r := range roles {
res.roles[r] = struct{}{}
}
return res
}
// Parse parses a set of roles.
// The returned set is always non-nil and contains all roles, including unknown (for compatibility with future versions).
// The returned slice contains roles unknown to the current version.
func Parse(str []string) (Set, []string) {
res := MakeSet()
var unknownRoles []string
for _, r := range str {
r = strings.TrimSpace(r)
// Client certificates generated by previous Talos versions contained one empty organization.
if r == "" {
continue
}
role := Role(r)
if _, ok := All.roles[role]; !ok {
unknownRoles = append(unknownRoles, r)
}
res.roles[role] = struct{}{}
}
return res, unknownRoles
}
// Strings returns a set as a slice of strings.
func (s Set) Strings() []string {
res := make([]string, 0, len(s.roles))
for r := range s.roles {
res = append(res, string(r))
}
sort.Strings(res)
return res
}
// IncludesAny returns true if there is a non-empty intersection between sets.
//
// Returns false if any set is empty.
func (s Set) IncludesAny(other Set) bool {
for r := range other.roles {
if _, ok := s.roles[r]; ok {
return true
}
}
return false
}
// Includes returns true if given role is present in the set.
func (s Set) Includes(role Role) bool {
_, ok := s.roles[role]
return ok
}