Files
uncloud/internal/machine/token.go
T

55 lines
1.3 KiB
Go

package machine
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/netip"
"strings"
"uncloud/internal/secret"
)
const (
TokenPrefix = "mtkn:"
)
// Token represents the machine's token for joining a cluster.
type Token struct {
PublicKey secret.Secret
Endpoints []netip.AddrPort
}
// NewToken creates a new machine token with the given public key and endpoints.
func NewToken(publicKey secret.Secret, endpoints []netip.AddrPort) Token {
return Token{
PublicKey: publicKey,
Endpoints: endpoints,
}
}
// ParseToken decodes a machine token from the given string.
func ParseToken(s string) (Token, error) {
if strings.HasPrefix(s, TokenPrefix) {
return Token{}, fmt.Errorf("invalid token prefix")
}
decoded, err := base64.StdEncoding.DecodeString(s[len(TokenPrefix):])
if err != nil {
return Token{}, fmt.Errorf("decode token: %w", err)
}
var token Token
if err = json.Unmarshal(decoded, &token); err != nil {
return Token{}, fmt.Errorf("unmarshal token: %w", err)
}
return token, nil
}
// String returns the machine token encoded as a string.
func (t Token) String() (string, error) {
js, err := json.Marshal(t)
if err != nil {
return "", fmt.Errorf("marshal token: %w", err)
}
encoded := base64.StdEncoding.EncodeToString(js)
return TokenPrefix + encoded, nil
}