184 lines
5.4 KiB
Go
184 lines
5.4 KiB
Go
package systemaccount
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"
|
|
|
|
v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3"
|
|
"github.com/rancher/rancher/pkg/ref"
|
|
"github.com/rancher/rancher/pkg/types/config"
|
|
"github.com/rancher/rancher/pkg/types/config/systemtokens"
|
|
"github.com/rancher/rancher/pkg/user"
|
|
"github.com/rancher/wrangler/v3/pkg/randomtoken"
|
|
errors2 "k8s.io/apimachinery/pkg/api/errors"
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
const (
|
|
clusterOwnerRole = "cluster-owner"
|
|
projectMemberRole = "project-member"
|
|
ClusterSystemAccountPrefix = "System account for Cluster "
|
|
ProjectSystemAccountPrefix = "System account for Project "
|
|
)
|
|
|
|
func NewManager(management *config.ManagementContext) *Manager {
|
|
return &Manager{
|
|
userManager: management.UserManager,
|
|
systemTokens: management.SystemTokens,
|
|
crtbs: management.Management.ClusterRoleTemplateBindings(""),
|
|
crts: management.Management.ClusterRegistrationTokens(""),
|
|
prtbs: management.Management.ProjectRoleTemplateBindings(""),
|
|
prtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(),
|
|
tokens: management.Management.Tokens(""),
|
|
users: management.Management.Users(""),
|
|
}
|
|
}
|
|
|
|
func NewManagerFromScale(management *config.ScaledContext) *Manager {
|
|
return &Manager{
|
|
userManager: management.UserManager,
|
|
systemTokens: management.SystemTokens,
|
|
crtbs: management.Management.ClusterRoleTemplateBindings(""),
|
|
crts: management.Management.ClusterRegistrationTokens(""),
|
|
prtbs: management.Management.ProjectRoleTemplateBindings(""),
|
|
prtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(),
|
|
tokens: management.Management.Tokens(""),
|
|
tokenLister: management.Management.Tokens("").Controller().Lister(),
|
|
users: management.Management.Users(""),
|
|
}
|
|
}
|
|
|
|
type Manager struct {
|
|
userManager user.Manager
|
|
systemTokens systemtokens.Interface
|
|
crtbs v3.ClusterRoleTemplateBindingInterface
|
|
crts v3.ClusterRegistrationTokenInterface
|
|
prtbs v3.ProjectRoleTemplateBindingInterface
|
|
prtbLister v3.ProjectRoleTemplateBindingLister
|
|
tokens v3.TokenInterface
|
|
tokenLister v3.TokenLister
|
|
users v3.UserInterface
|
|
}
|
|
|
|
func (s *Manager) CreateSystemAccount(cluster *v3.Cluster) error {
|
|
user, err := s.GetSystemUser(cluster.Name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
bindingName := user.Name + "-admin"
|
|
_, err = s.crtbs.GetNamespaced(cluster.Name, bindingName, v1.GetOptions{})
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
_, err = s.crtbs.Create(&v3.ClusterRoleTemplateBinding{
|
|
ObjectMeta: v1.ObjectMeta{
|
|
Name: bindingName,
|
|
Namespace: cluster.Name,
|
|
},
|
|
ClusterName: cluster.Name,
|
|
UserName: user.Name,
|
|
RoleTemplateName: clusterOwnerRole,
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
func (s *Manager) GetSystemUser(clusterName string) (*v3.User, error) {
|
|
return s.userManager.EnsureUser(fmt.Sprintf("system://%s", clusterName), ClusterSystemAccountPrefix+clusterName)
|
|
}
|
|
|
|
func (s *Manager) GetOrCreateSystemClusterToken(clusterName string) (string, error) {
|
|
token := ""
|
|
|
|
crt, err := s.crts.GetNamespaced(clusterName, "system", v1.GetOptions{})
|
|
if errors2.IsNotFound(err) {
|
|
token, err = randomtoken.Generate()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
crt = &v3.ClusterRegistrationToken{
|
|
ObjectMeta: v1.ObjectMeta{
|
|
Name: "system",
|
|
Namespace: clusterName,
|
|
},
|
|
Spec: v32.ClusterRegistrationTokenSpec{
|
|
ClusterName: clusterName,
|
|
},
|
|
Status: v32.ClusterRegistrationTokenStatus{
|
|
Token: token,
|
|
},
|
|
}
|
|
|
|
if _, err := s.crts.Create(crt); err != nil {
|
|
return "", err
|
|
}
|
|
} else if err != nil {
|
|
return "", err
|
|
} else {
|
|
token = crt.Status.Token
|
|
}
|
|
|
|
return token, nil
|
|
}
|
|
|
|
func (s *Manager) GetOrCreateProjectSystemAccount(projectID string) error {
|
|
_, projectName := ref.Parse(projectID)
|
|
|
|
u, err := s.GetProjectSystemUser(projectName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
bindingName := u.Name + "-member"
|
|
_, err = s.prtbLister.Get(projectName, bindingName)
|
|
if err != nil {
|
|
if !errors2.IsNotFound(err) {
|
|
return err
|
|
}
|
|
// prtb does not exist in cache, attempt to create it
|
|
prtb := &v3.ProjectRoleTemplateBinding{
|
|
ObjectMeta: v1.ObjectMeta{
|
|
Name: bindingName,
|
|
Namespace: projectName,
|
|
},
|
|
ProjectName: projectID,
|
|
UserName: u.Name,
|
|
RoleTemplateName: projectMemberRole,
|
|
}
|
|
if _, err := s.prtbs.Create(prtb); err != nil && !errors2.IsAlreadyExists(err) {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Manager) GetProjectSystemUser(projectName string) (*v3.User, error) {
|
|
return s.userManager.EnsureUser(fmt.Sprintf("system://%s", projectName), ProjectSystemAccountPrefix+projectName)
|
|
}
|
|
|
|
func (s *Manager) CreateProjectHelmSystemToken(projectName string) (string, error) {
|
|
user, err := s.GetProjectSystemUser(projectName)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return s.systemTokens.EnsureSystemToken(projectName+"-helm", "Helm token for project "+projectName, "helm", user.Name, nil, true)
|
|
}
|
|
|
|
func (s *Manager) RemoveSystemAccount(userID string) error {
|
|
u, err := s.userManager.GetUserByPrincipalID(fmt.Sprintf("system://%s", userID))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if u == nil {
|
|
// user not found, must have been removed
|
|
return nil
|
|
}
|
|
if err := s.users.Delete(u.Name, &v1.DeleteOptions{}); err != nil && !errors2.IsNotFound(err) && !errors2.IsGone(err) {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|