mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-05-10 19:27:59 +00:00
95 lines
2.9 KiB
Go
95 lines
2.9 KiB
Go
package tokenrequest
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
cloudevents "github.com/cloudevents/sdk-go/v2"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/klog/v2"
|
|
|
|
sace "open-cluster-management.io/sdk-go/pkg/cloudevents/clients/serviceaccount"
|
|
"open-cluster-management.io/sdk-go/pkg/cloudevents/generic/types"
|
|
"open-cluster-management.io/sdk-go/pkg/cloudevents/server"
|
|
|
|
"open-cluster-management.io/ocm/pkg/server/services"
|
|
)
|
|
|
|
type TokenRequestService struct {
|
|
client kubernetes.Interface
|
|
codec *sace.TokenRequestCodec
|
|
handler server.EventHandler
|
|
}
|
|
|
|
// NewTokenRequestService creates a new TokenRequestService
|
|
func NewTokenRequestService(client kubernetes.Interface) server.Service {
|
|
return &TokenRequestService{
|
|
client: client,
|
|
codec: sace.NewTokenRequestCodec(),
|
|
}
|
|
}
|
|
|
|
func (t *TokenRequestService) List(ctx context.Context, listOpts types.ListOptions) ([]*cloudevents.Event, error) {
|
|
// resync is not needed, so list is not required
|
|
return nil, nil
|
|
}
|
|
|
|
func (t *TokenRequestService) HandleStatusUpdate(ctx context.Context, evt *cloudevents.Event) error {
|
|
logger := klog.FromContext(ctx)
|
|
|
|
eventType, err := types.ParseCloudEventsType(evt.Type())
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse cloud event type %s, %v", evt.Type(), err)
|
|
}
|
|
|
|
tokenRequest, err := t.codec.Decode(evt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
requestID := tokenRequest.UID
|
|
|
|
logger.V(4).Info("handle token request", "namespace", tokenRequest.Namespace,
|
|
"serviceAccount", tokenRequest.Name, "requestID", requestID,
|
|
"subResource", eventType.SubResource, "actionType", eventType.Action)
|
|
|
|
switch eventType.Action {
|
|
case types.CreateRequestAction:
|
|
// Clear the UID to avoid conflict with the ServiceAccount UID validation
|
|
// introduced by the TokenRequestServiceAccountUIDValidation feature gate (k8s 1.34+).
|
|
tokenRequest.UID = ""
|
|
// Create a token for the service account
|
|
tokenResponse, err := t.client.CoreV1().ServiceAccounts(tokenRequest.Namespace).CreateToken(ctx, tokenRequest.Name, tokenRequest, metav1.CreateOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// set request id back
|
|
tokenResponse.UID = requestID
|
|
|
|
// Notify the handler that the token is ready for retrieval
|
|
eventTypes := types.CloudEventsType{
|
|
CloudEventsDataType: sace.TokenRequestDataType,
|
|
SubResource: types.SubResourceSpec,
|
|
Action: types.CreateRequestAction,
|
|
}
|
|
evt, err := t.codec.Encode(services.CloudEventsSourceKube, eventTypes, tokenResponse)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to encode token response: %v", err)
|
|
}
|
|
|
|
if err := t.handler.HandleEvent(ctx, evt); err != nil {
|
|
return fmt.Errorf("failed to notify handler: %v", err)
|
|
}
|
|
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("unsupported action %s for tokenRequest %s/%s", eventType.Action, tokenRequest.Namespace, tokenRequest.Name)
|
|
}
|
|
}
|
|
|
|
func (t *TokenRequestService) RegisterHandler(ctx context.Context, handler server.EventHandler) {
|
|
t.handler = handler
|
|
}
|