mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-03-04 14:39:30 +00:00
With Amazon STS and kubernetes cluster is configured with OIDC identity provider, credentials to access Amazon KMS can be fetched using oidc-token(serviceaccount token). Each tenant/namespace needs to create a secret with aws region, role and CMK ARN. Ceph-CSI will assume the given role with oidc token and access aws KMS, with given CMK to encrypt/decrypt DEK which will stored in the image metdata. Refer: https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html Resolves: #2879 Signed-off-by: Rakshith R <rar@redhat.com>
169 lines
5.3 KiB
Go
169 lines
5.3 KiB
Go
package middleware
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/internal/rand"
|
|
"github.com/aws/aws-sdk-go-v2/internal/sdk"
|
|
"github.com/aws/smithy-go/logging"
|
|
"github.com/aws/smithy-go/middleware"
|
|
smithyrand "github.com/aws/smithy-go/rand"
|
|
smithyhttp "github.com/aws/smithy-go/transport/http"
|
|
)
|
|
|
|
// ClientRequestID is a Smithy BuildMiddleware that will generate a unique ID for logical API operation
|
|
// invocation.
|
|
type ClientRequestID struct{}
|
|
|
|
// ID the identifier for the ClientRequestID
|
|
func (r *ClientRequestID) ID() string {
|
|
return "ClientRequestID"
|
|
}
|
|
|
|
// HandleBuild attaches a unique operation invocation id for the operation to the request
|
|
func (r ClientRequestID) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (
|
|
out middleware.BuildOutput, metadata middleware.Metadata, err error,
|
|
) {
|
|
req, ok := in.Request.(*smithyhttp.Request)
|
|
if !ok {
|
|
return out, metadata, fmt.Errorf("unknown transport type %T", req)
|
|
}
|
|
|
|
invocationID, err := smithyrand.NewUUID(rand.Reader).GetUUID()
|
|
if err != nil {
|
|
return out, metadata, err
|
|
}
|
|
|
|
const invocationIDHeader = "Amz-Sdk-Invocation-Id"
|
|
req.Header[invocationIDHeader] = append(req.Header[invocationIDHeader][:0], invocationID)
|
|
|
|
return next.HandleBuild(ctx, in)
|
|
}
|
|
|
|
// RecordResponseTiming records the response timing for the SDK client requests.
|
|
type RecordResponseTiming struct{}
|
|
|
|
// ID is the middleware identifier
|
|
func (a *RecordResponseTiming) ID() string {
|
|
return "RecordResponseTiming"
|
|
}
|
|
|
|
// HandleDeserialize calculates response metadata and clock skew
|
|
func (a RecordResponseTiming) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
|
|
out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
|
|
) {
|
|
out, metadata, err = next.HandleDeserialize(ctx, in)
|
|
responseAt := sdk.NowTime()
|
|
setResponseAt(&metadata, responseAt)
|
|
|
|
var serverTime time.Time
|
|
|
|
switch resp := out.RawResponse.(type) {
|
|
case *smithyhttp.Response:
|
|
respDateHeader := resp.Header.Get("Date")
|
|
if len(respDateHeader) == 0 {
|
|
break
|
|
}
|
|
var parseErr error
|
|
serverTime, parseErr = smithyhttp.ParseTime(respDateHeader)
|
|
if parseErr != nil {
|
|
logger := middleware.GetLogger(ctx)
|
|
logger.Logf(logging.Warn, "failed to parse response Date header value, got %v",
|
|
parseErr.Error())
|
|
break
|
|
}
|
|
setServerTime(&metadata, serverTime)
|
|
}
|
|
|
|
if !serverTime.IsZero() {
|
|
attemptSkew := serverTime.Sub(responseAt)
|
|
setAttemptSkew(&metadata, attemptSkew)
|
|
}
|
|
|
|
return out, metadata, err
|
|
}
|
|
|
|
type responseAtKey struct{}
|
|
|
|
// GetResponseAt returns the time response was received at.
|
|
func GetResponseAt(metadata middleware.Metadata) (v time.Time, ok bool) {
|
|
v, ok = metadata.Get(responseAtKey{}).(time.Time)
|
|
return v, ok
|
|
}
|
|
|
|
// setResponseAt sets the response time on the metadata.
|
|
func setResponseAt(metadata *middleware.Metadata, v time.Time) {
|
|
metadata.Set(responseAtKey{}, v)
|
|
}
|
|
|
|
type serverTimeKey struct{}
|
|
|
|
// GetServerTime returns the server time for response.
|
|
func GetServerTime(metadata middleware.Metadata) (v time.Time, ok bool) {
|
|
v, ok = metadata.Get(serverTimeKey{}).(time.Time)
|
|
return v, ok
|
|
}
|
|
|
|
// setServerTime sets the server time on the metadata.
|
|
func setServerTime(metadata *middleware.Metadata, v time.Time) {
|
|
metadata.Set(serverTimeKey{}, v)
|
|
}
|
|
|
|
type attemptSkewKey struct{}
|
|
|
|
// GetAttemptSkew returns Attempt clock skew for response from metadata.
|
|
func GetAttemptSkew(metadata middleware.Metadata) (v time.Duration, ok bool) {
|
|
v, ok = metadata.Get(attemptSkewKey{}).(time.Duration)
|
|
return v, ok
|
|
}
|
|
|
|
// setAttemptSkew sets the attempt clock skew on the metadata.
|
|
func setAttemptSkew(metadata *middleware.Metadata, v time.Duration) {
|
|
metadata.Set(attemptSkewKey{}, v)
|
|
}
|
|
|
|
// AddClientRequestIDMiddleware adds ClientRequestID to the middleware stack
|
|
func AddClientRequestIDMiddleware(stack *middleware.Stack) error {
|
|
return stack.Build.Add(&ClientRequestID{}, middleware.After)
|
|
}
|
|
|
|
// AddRecordResponseTiming adds RecordResponseTiming middleware to the
|
|
// middleware stack.
|
|
func AddRecordResponseTiming(stack *middleware.Stack) error {
|
|
return stack.Deserialize.Add(&RecordResponseTiming{}, middleware.After)
|
|
}
|
|
|
|
// rawResponseKey is the accessor key used to store and access the
|
|
// raw response within the response metadata.
|
|
type rawResponseKey struct{}
|
|
|
|
// addRawResponse middleware adds raw response on to the metadata
|
|
type addRawResponse struct{}
|
|
|
|
// ID the identifier for the ClientRequestID
|
|
func (m *addRawResponse) ID() string {
|
|
return "AddRawResponseToMetadata"
|
|
}
|
|
|
|
// HandleDeserialize adds raw response on the middleware metadata
|
|
func (m addRawResponse) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
|
|
out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
|
|
) {
|
|
out, metadata, err = next.HandleDeserialize(ctx, in)
|
|
metadata.Set(rawResponseKey{}, out.RawResponse)
|
|
return out, metadata, err
|
|
}
|
|
|
|
// AddRawResponseToMetadata adds middleware to the middleware stack that
|
|
// store raw response on to the metadata.
|
|
func AddRawResponseToMetadata(stack *middleware.Stack) error {
|
|
return stack.Deserialize.Add(&addRawResponse{}, middleware.Before)
|
|
}
|
|
|
|
// GetRawResponse returns raw response set on metadata
|
|
func GetRawResponse(metadata middleware.Metadata) interface{} {
|
|
return metadata.Get(rawResponseKey{})
|
|
}
|