117 lines
3.3 KiB
Go
117 lines
3.3 KiB
Go
package systemtokens
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/rancher/rancher/pkg/auth/tokens"
|
|
v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3"
|
|
"github.com/rancher/rancher/pkg/types/config"
|
|
"github.com/rancher/rancher/pkg/types/config/systemtokens"
|
|
"github.com/rancher/wrangler/v3/pkg/randomtoken"
|
|
"github.com/sirupsen/logrus"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
func NewSystemTokensFromScale(mgmt *config.ScaledContext) systemtokens.Interface {
|
|
return &systemTokens{
|
|
tokenLister: mgmt.Management.Tokens("").Controller().Lister(),
|
|
tokenClient: mgmt.Management.Tokens(""),
|
|
}
|
|
}
|
|
|
|
type systemTokens struct {
|
|
tokenClient v3.TokenInterface
|
|
tokenLister v3.TokenLister
|
|
}
|
|
|
|
// EnsureSystemToken creates tokens or updates their values if they already exist and returns their value.
|
|
// TTL defaults to 1 hour, after that this method will auto-refresh. If your token will be in use for more
|
|
// than one hour without calling this method again you must pass in an overrideTTL.
|
|
// However, if the overrideTTL is 0 the token will never be cleaned up; this should be done with caution.
|
|
func (t *systemTokens) EnsureSystemToken(tokenName, description, kind, username string, overrideTTL *int64, randomize bool) (string, error) {
|
|
var err error
|
|
if !randomize {
|
|
_, err = t.tokenLister.Get("", tokenName)
|
|
if err != nil && !apierrors.IsNotFound(err) {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
// needs fresh token because its missing or expired
|
|
val, err := t.createOrUpdateSystemToken(tokenName, description, kind, username, overrideTTL, randomize)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return val, nil
|
|
}
|
|
|
|
func (t *systemTokens) DeleteToken(tokenName string) error {
|
|
return t.tokenClient.Delete(tokenName, &v1.DeleteOptions{})
|
|
}
|
|
|
|
// Creates token obj with hashed token, returns token. Overwrites if pre-existing.
|
|
func (t *systemTokens) createOrUpdateSystemToken(tokenName, description, kind, userName string, overrideTTL *int64, randomize bool) (string, error) {
|
|
if strings.HasPrefix(tokenName, "token-") {
|
|
return "", errors.New("token names can't start with token-")
|
|
}
|
|
key, err := randomtoken.Generate()
|
|
if err != nil {
|
|
return "", errors.New("failed to generate token key")
|
|
}
|
|
|
|
if !randomize {
|
|
token, err := t.tokenLister.Get("", tokenName)
|
|
if err != nil {
|
|
if !apierrors.IsNotFound(err) {
|
|
return "", err
|
|
}
|
|
}
|
|
if err == nil {
|
|
if err := t.tokenClient.Delete(token.Name, &v1.DeleteOptions{}); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
}
|
|
|
|
// not found error, make new token
|
|
token := &v3.Token{
|
|
ObjectMeta: v1.ObjectMeta{
|
|
Name: tokenName,
|
|
Labels: map[string]string{
|
|
tokens.UserIDLabel: userName,
|
|
tokens.TokenKindLabel: kind,
|
|
},
|
|
},
|
|
TTLMillis: 3600000, // 1 hour, token purge daemon will cleanup
|
|
Description: description,
|
|
UserID: userName,
|
|
AuthProvider: "local",
|
|
IsDerived: true,
|
|
Token: key,
|
|
}
|
|
if overrideTTL != nil {
|
|
token.TTLMillis = *overrideTTL
|
|
}
|
|
if randomize {
|
|
token.ObjectMeta.Name = ""
|
|
token.ObjectMeta.GenerateName = tokenName
|
|
}
|
|
|
|
err = tokens.ConvertTokenKeyToHash(token)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
logrus.Infof("Creating system token for %v, token: %v", userName, tokenName)
|
|
token, err = t.tokenClient.Create(token)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
fullVal := fmt.Sprintf("%s:%s", token.Name, key)
|
|
return fullVal, nil
|
|
}
|