mirror of
https://github.com/siderolabs/talos.git
synced 2025-09-13 09:51:10 +02:00
120 lines
2.7 KiB
Go
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
|
|
}
|