go.mod: update to images@v0.117.0

This commit updates to images v0.117.0 so that the cross-distro.sh
test works again (images removed fedora-39.json in main but the
uses the previous version of images that includes fedora-39 so
there is a mismatch (we should look into if there is a way to
get github.com/osbuild/images@latest instead of main in the
cross-arch test).

It also updates all the vendor stuff that got pulled via the
new images release (which is giantonormous).

This update requires updating the Go version to 1.22.8
This commit is contained in:
Michael Vogt 2025-02-14 11:08:48 +01:00 committed by Achilleas Koutsou
parent 886ddc0bcc
commit 409b4f6048
584 changed files with 60776 additions and 50181 deletions

View file

@ -3,7 +3,14 @@
[![Docs](https://godoc.org/github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric?status.svg)](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric)
[![Apache License][license-image]][license-url]
OpenTelemetry Google Cloud Monitoring Exporter allow the user to send collected metrics to Google Cloud.
OpenTelemetry Google Cloud Monitoring Exporter allows the user to send collected metrics to Google Cloud.
To get started with instrumentation in Google Cloud, see [Generate traces and metrics with
Go](https://cloud.google.com/stackdriver/docs/instrumentation/setup/go).
To learn more about instrumentation and observability, including opinionated recommendations
for Google Cloud Observability, visit [Instrumentation and
observability](https://cloud.google.com/stackdriver/docs/instrumentation/overview).
[Google Cloud Monitoring](https://cloud.google.com/monitoring) provides visibility into the performance, uptime, and overall health of cloud-powered applications. It collects metrics, events, and metadata from Google Cloud, Amazon Web Services, hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch, and many others. Operations ingests that data and generates insights via dashboards, charts, and alerts. Cloud Monitoring alerting helps you collaborate by integrating with Slack, PagerDuty, and more.

View file

@ -68,7 +68,7 @@ type key struct {
libraryname string
}
func keyOf(metrics metricdata.Metrics, library instrumentation.Library) key {
func keyOf(metrics metricdata.Metrics, library instrumentation.Scope) key {
return key{
name: metrics.Name,
libraryname: library.Name,
@ -426,7 +426,7 @@ func recordToMdpbKindType(a metricdata.Aggregation) (googlemetricpb.MetricDescri
}
// recordToMpb converts data from records to Metric proto type for Cloud Monitoring.
func (me *metricExporter) recordToMpb(metrics metricdata.Metrics, attributes attribute.Set, library instrumentation.Library, extraLabels *attribute.Set) *googlemetricpb.Metric {
func (me *metricExporter) recordToMpb(metrics metricdata.Metrics, attributes attribute.Set, library instrumentation.Scope, extraLabels *attribute.Set) *googlemetricpb.Metric {
me.mdLock.RLock()
defer me.mdLock.RUnlock()
k := keyOf(metrics, library)

View file

@ -92,7 +92,7 @@ type options struct {
// WithProjectID sets Google Cloud Platform project as projectID.
// Without using this option, it automatically detects the project ID
// from the default credential detection process.
// Please find the detailed order of the default credentail detection proecess on the doc:
// Please find the detailed order of the default credential detection process on the doc:
// https://godoc.org/golang.org/x/oauth2/google#FindDefaultCredentials
func WithProjectID(id string) func(o *options) {
return func(o *options) {

View file

@ -17,5 +17,5 @@ package metric
// Version is the current release version of the OpenTelemetry
// Operations Metric Exporter in use.
func Version() string {
return "0.48.1"
return "0.49.0"
}

View file

@ -221,9 +221,8 @@ func commonResourceAttributesToMonitoredResource(cloudPlatform string, attrs Rea
return createMonitoredResource(k8sPod, attrs)
} else if _, ok := attrs.GetString(string(semconv.K8SNodeNameKey)); ok {
return createMonitoredResource(k8sNode, attrs)
} else {
return createMonitoredResource(k8sCluster, attrs)
}
return createMonitoredResource(k8sCluster, attrs)
}
// Fallback to generic_task

View file

@ -3,4 +3,4 @@
package aws
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.30.4"
const goModuleVersion = "1.32.7"

View file

@ -1,320 +0,0 @@
// Package metrics implements metrics gathering for SDK development purposes.
//
// This package is designated as private and is intended for use only by the
// AWS client runtime. The exported API therein is not considered stable and
// is subject to breaking changes without notice.
package metrics
import (
"context"
"encoding/json"
"fmt"
"sync"
"time"
"github.com/aws/smithy-go/middleware"
)
const (
// ServiceIDKey is the key for the service ID metric.
ServiceIDKey = "ServiceId"
// OperationNameKey is the key for the operation name metric.
OperationNameKey = "OperationName"
// ClientRequestIDKey is the key for the client request ID metric.
ClientRequestIDKey = "ClientRequestId"
// APICallDurationKey is the key for the API call duration metric.
APICallDurationKey = "ApiCallDuration"
// APICallSuccessfulKey is the key for the API call successful metric.
APICallSuccessfulKey = "ApiCallSuccessful"
// MarshallingDurationKey is the key for the marshalling duration metric.
MarshallingDurationKey = "MarshallingDuration"
// InThroughputKey is the key for the input throughput metric.
InThroughputKey = "InThroughput"
// OutThroughputKey is the key for the output throughput metric.
OutThroughputKey = "OutThroughput"
// RetryCountKey is the key for the retry count metric.
RetryCountKey = "RetryCount"
// HTTPStatusCodeKey is the key for the HTTP status code metric.
HTTPStatusCodeKey = "HttpStatusCode"
// AWSExtendedRequestIDKey is the key for the AWS extended request ID metric.
AWSExtendedRequestIDKey = "AwsExtendedRequestId"
// AWSRequestIDKey is the key for the AWS request ID metric.
AWSRequestIDKey = "AwsRequestId"
// BackoffDelayDurationKey is the key for the backoff delay duration metric.
BackoffDelayDurationKey = "BackoffDelayDuration"
// StreamThroughputKey is the key for the stream throughput metric.
StreamThroughputKey = "Throughput"
// ConcurrencyAcquireDurationKey is the key for the concurrency acquire duration metric.
ConcurrencyAcquireDurationKey = "ConcurrencyAcquireDuration"
// PendingConcurrencyAcquiresKey is the key for the pending concurrency acquires metric.
PendingConcurrencyAcquiresKey = "PendingConcurrencyAcquires"
// SigningDurationKey is the key for the signing duration metric.
SigningDurationKey = "SigningDuration"
// UnmarshallingDurationKey is the key for the unmarshalling duration metric.
UnmarshallingDurationKey = "UnmarshallingDuration"
// TimeToFirstByteKey is the key for the time to first byte metric.
TimeToFirstByteKey = "TimeToFirstByte"
// ServiceCallDurationKey is the key for the service call duration metric.
ServiceCallDurationKey = "ServiceCallDuration"
// EndpointResolutionDurationKey is the key for the endpoint resolution duration metric.
EndpointResolutionDurationKey = "EndpointResolutionDuration"
// AttemptNumberKey is the key for the attempt number metric.
AttemptNumberKey = "AttemptNumber"
// MaxConcurrencyKey is the key for the max concurrency metric.
MaxConcurrencyKey = "MaxConcurrency"
// AvailableConcurrencyKey is the key for the available concurrency metric.
AvailableConcurrencyKey = "AvailableConcurrency"
)
// MetricPublisher provides the interface to provide custom MetricPublishers.
// PostRequestMetrics will be invoked by the MetricCollection middleware to post request.
// PostStreamMetrics will be invoked by ReadCloserWithMetrics to post stream metrics.
type MetricPublisher interface {
PostRequestMetrics(*MetricData) error
PostStreamMetrics(*MetricData) error
}
// Serializer provides the interface to provide custom Serializers.
// Serialize will transform any input object in its corresponding string representation.
type Serializer interface {
Serialize(obj interface{}) (string, error)
}
// DefaultSerializer is an implementation of the Serializer interface.
type DefaultSerializer struct{}
// Serialize uses the default JSON serializer to obtain the string representation of an object.
func (DefaultSerializer) Serialize(obj interface{}) (string, error) {
bytes, err := json.Marshal(obj)
if err != nil {
return "", err
}
return string(bytes), nil
}
type metricContextKey struct{}
// MetricContext contains fields to store metric-related information.
type MetricContext struct {
connectionCounter *SharedConnectionCounter
publisher MetricPublisher
data *MetricData
}
// MetricData stores the collected metric data.
type MetricData struct {
RequestStartTime time.Time
RequestEndTime time.Time
APICallDuration time.Duration
SerializeStartTime time.Time
SerializeEndTime time.Time
MarshallingDuration time.Duration
ResolveEndpointStartTime time.Time
ResolveEndpointEndTime time.Time
EndpointResolutionDuration time.Duration
GetIdentityStartTime time.Time
GetIdentityEndTime time.Time
InThroughput float64
OutThroughput float64
RetryCount int
Success uint8
StatusCode int
ClientRequestID string
ServiceID string
OperationName string
PartitionID string
Region string
UserAgent string
RequestContentLength int64
Stream StreamMetrics
Attempts []AttemptMetrics
}
// StreamMetrics stores metrics related to streaming data.
type StreamMetrics struct {
ReadDuration time.Duration
ReadBytes int64
Throughput float64
}
// AttemptMetrics stores metrics related to individual attempts.
type AttemptMetrics struct {
ServiceCallStart time.Time
ServiceCallEnd time.Time
ServiceCallDuration time.Duration
FirstByteTime time.Time
TimeToFirstByte time.Duration
ConnRequestedTime time.Time
ConnObtainedTime time.Time
ConcurrencyAcquireDuration time.Duration
SignStartTime time.Time
SignEndTime time.Time
SigningDuration time.Duration
DeserializeStartTime time.Time
DeserializeEndTime time.Time
UnMarshallingDuration time.Duration
RetryDelay time.Duration
ResponseContentLength int64
StatusCode int
RequestID string
ExtendedRequestID string
HTTPClient string
MaxConcurrency int
PendingConnectionAcquires int
AvailableConcurrency int
ActiveRequests int
ReusedConnection bool
}
// Data returns the MetricData associated with the MetricContext.
func (mc *MetricContext) Data() *MetricData {
return mc.data
}
// ConnectionCounter returns the SharedConnectionCounter associated with the MetricContext.
func (mc *MetricContext) ConnectionCounter() *SharedConnectionCounter {
return mc.connectionCounter
}
// Publisher returns the MetricPublisher associated with the MetricContext.
func (mc *MetricContext) Publisher() MetricPublisher {
return mc.publisher
}
// ComputeRequestMetrics calculates and populates derived metrics based on the collected data.
func (md *MetricData) ComputeRequestMetrics() {
for idx := range md.Attempts {
attempt := &md.Attempts[idx]
attempt.ConcurrencyAcquireDuration = attempt.ConnObtainedTime.Sub(attempt.ConnRequestedTime)
attempt.SigningDuration = attempt.SignEndTime.Sub(attempt.SignStartTime)
attempt.UnMarshallingDuration = attempt.DeserializeEndTime.Sub(attempt.DeserializeStartTime)
attempt.TimeToFirstByte = attempt.FirstByteTime.Sub(attempt.ServiceCallStart)
attempt.ServiceCallDuration = attempt.ServiceCallEnd.Sub(attempt.ServiceCallStart)
}
md.APICallDuration = md.RequestEndTime.Sub(md.RequestStartTime)
md.MarshallingDuration = md.SerializeEndTime.Sub(md.SerializeStartTime)
md.EndpointResolutionDuration = md.ResolveEndpointEndTime.Sub(md.ResolveEndpointStartTime)
md.RetryCount = len(md.Attempts) - 1
latestAttempt, err := md.LatestAttempt()
if err != nil {
fmt.Printf("error retrieving attempts data due to: %s. Skipping Throughput metrics", err.Error())
} else {
md.StatusCode = latestAttempt.StatusCode
if md.Success == 1 {
if latestAttempt.ResponseContentLength > 0 && latestAttempt.ServiceCallDuration > 0 {
md.InThroughput = float64(latestAttempt.ResponseContentLength) / latestAttempt.ServiceCallDuration.Seconds()
}
if md.RequestContentLength > 0 && latestAttempt.ServiceCallDuration > 0 {
md.OutThroughput = float64(md.RequestContentLength) / latestAttempt.ServiceCallDuration.Seconds()
}
}
}
}
// LatestAttempt returns the latest attempt metrics.
// It returns an error if no attempts are initialized.
func (md *MetricData) LatestAttempt() (*AttemptMetrics, error) {
if md.Attempts == nil || len(md.Attempts) == 0 {
return nil, fmt.Errorf("no attempts initialized. NewAttempt() should be called first")
}
return &md.Attempts[len(md.Attempts)-1], nil
}
// NewAttempt initializes new attempt metrics.
func (md *MetricData) NewAttempt() {
if md.Attempts == nil {
md.Attempts = []AttemptMetrics{}
}
md.Attempts = append(md.Attempts, AttemptMetrics{})
}
// SharedConnectionCounter is a counter shared across API calls.
type SharedConnectionCounter struct {
mu sync.Mutex
activeRequests int
pendingConnectionAcquire int
}
// ActiveRequests returns the count of active requests.
func (cc *SharedConnectionCounter) ActiveRequests() int {
cc.mu.Lock()
defer cc.mu.Unlock()
return cc.activeRequests
}
// PendingConnectionAcquire returns the count of pending connection acquires.
func (cc *SharedConnectionCounter) PendingConnectionAcquire() int {
cc.mu.Lock()
defer cc.mu.Unlock()
return cc.pendingConnectionAcquire
}
// AddActiveRequest increments the count of active requests.
func (cc *SharedConnectionCounter) AddActiveRequest() {
cc.mu.Lock()
defer cc.mu.Unlock()
cc.activeRequests++
}
// RemoveActiveRequest decrements the count of active requests.
func (cc *SharedConnectionCounter) RemoveActiveRequest() {
cc.mu.Lock()
defer cc.mu.Unlock()
cc.activeRequests--
}
// AddPendingConnectionAcquire increments the count of pending connection acquires.
func (cc *SharedConnectionCounter) AddPendingConnectionAcquire() {
cc.mu.Lock()
defer cc.mu.Unlock()
cc.pendingConnectionAcquire++
}
// RemovePendingConnectionAcquire decrements the count of pending connection acquires.
func (cc *SharedConnectionCounter) RemovePendingConnectionAcquire() {
cc.mu.Lock()
defer cc.mu.Unlock()
cc.pendingConnectionAcquire--
}
// InitMetricContext initializes the metric context with the provided counter and publisher.
// It returns the updated context.
func InitMetricContext(
ctx context.Context, counter *SharedConnectionCounter, publisher MetricPublisher,
) context.Context {
if middleware.GetStackValue(ctx, metricContextKey{}) == nil {
ctx = middleware.WithStackValue(ctx, metricContextKey{}, &MetricContext{
connectionCounter: counter,
publisher: publisher,
data: &MetricData{
Attempts: []AttemptMetrics{},
Stream: StreamMetrics{},
},
})
}
return ctx
}
// Context returns the metric context from the given context.
// It returns nil if the metric context is not found.
func Context(ctx context.Context) *MetricContext {
mctx := middleware.GetStackValue(ctx, metricContextKey{})
if mctx == nil {
return nil
}
return mctx.(*MetricContext)
}

View file

@ -4,6 +4,7 @@ import (
"context"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -45,6 +46,9 @@ func (m *RequestIDRetriever) HandleDeserialize(ctx context.Context, in middlewar
if v := resp.Header.Get(h); len(v) != 0 {
// set reqID on metadata for successful responses.
SetRequestIDMetadata(&metadata, v)
span, _ := tracing.GetSpan(ctx)
span.SetProperty("aws.request_id", v)
break
}
}

View file

@ -34,6 +34,9 @@ const (
FeatureMetadata2
)
// Hardcoded value to specify which version of the user agent we're using
const uaMetadata = "ua/2.1"
func (k SDKAgentKeyType) string() string {
switch k {
case APIMetadata:
@ -85,6 +88,7 @@ const (
UserAgentFeatureS3ExpressBucket = "J"
UserAgentFeatureS3AccessGrants = "K" // not yet implemented
UserAgentFeatureGZIPRequestCompression = "L"
UserAgentFeatureProtocolRPCV2CBOR = "M"
)
// RequestUserAgent is a build middleware that set the User-Agent for the request.
@ -106,6 +110,7 @@ type RequestUserAgent struct {
func NewRequestUserAgent() *RequestUserAgent {
userAgent, sdkAgent := smithyhttp.NewUserAgentBuilder(), smithyhttp.NewUserAgentBuilder()
addProductName(userAgent)
addUserAgentMetadata(userAgent)
addProductName(sdkAgent)
r := &RequestUserAgent{
@ -133,6 +138,10 @@ func addProductName(builder *smithyhttp.UserAgentBuilder) {
builder.AddKeyValue(aws.SDKName, aws.SDKVersion)
}
func addUserAgentMetadata(builder *smithyhttp.UserAgentBuilder) {
builder.AddKey(uaMetadata)
}
// AddUserAgentKey retrieves a requestUserAgent from the provided stack, or initializes one.
func AddUserAgentKey(key string) func(*middleware.Stack) error {
return func(stack *middleware.Stack) error {
@ -257,10 +266,10 @@ func (u *RequestUserAgent) HandleBuild(ctx context.Context, in middleware.BuildI
func (u *RequestUserAgent) addHTTPUserAgent(request *smithyhttp.Request) {
const userAgent = "User-Agent"
updateHTTPHeader(request, userAgent, u.userAgent.Build())
if len(u.features) > 0 {
updateHTTPHeader(request, userAgent, buildFeatureMetrics(u.features))
}
updateHTTPHeader(request, userAgent, u.userAgent.Build())
}
func (u *RequestUserAgent) addHTTPSDKAgent(request *smithyhttp.Request) {

View file

@ -0,0 +1,51 @@
package retry
import (
"context"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
)
type attemptMetrics struct {
Attempts metrics.Int64Counter
Errors metrics.Int64Counter
AttemptDuration metrics.Float64Histogram
}
func newAttemptMetrics(meter metrics.Meter) (*attemptMetrics, error) {
m := &attemptMetrics{}
var err error
m.Attempts, err = meter.Int64Counter("client.call.attempts", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "{attempt}"
o.Description = "The number of attempts for an individual operation"
})
if err != nil {
return nil, err
}
m.Errors, err = meter.Int64Counter("client.call.errors", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "{error}"
o.Description = "The number of errors for an operation"
})
if err != nil {
return nil, err
}
m.AttemptDuration, err = meter.Float64Histogram("client.call.attempt_duration", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = "The time it takes to connect to the service, send the request, and get back HTTP status code and headers (including time queued waiting to be sent)"
})
if err != nil {
return nil, err
}
return m, nil
}
func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption {
return func(o *metrics.RecordMetricOptions) {
o.Properties.Set("rpc.service", middleware.GetServiceID(ctx))
o.Properties.Set("rpc.method", middleware.GetOperationName(ctx))
}
}

View file

@ -8,14 +8,16 @@ import (
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/aws/middleware/private/metrics"
internalcontext "github.com/aws/aws-sdk-go-v2/internal/context"
"github.com/aws/smithy-go"
"github.com/aws/aws-sdk-go-v2/aws"
awsmiddle "github.com/aws/aws-sdk-go-v2/aws/middleware"
"github.com/aws/aws-sdk-go-v2/internal/sdk"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
smithymiddle "github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
"github.com/aws/smithy-go/transport/http"
)
@ -38,6 +40,9 @@ type Attempt struct {
// attempts are reached.
LogAttempts bool
// A Meter instance for recording retry-related metrics.
OperationMeter metrics.Meter
retryer aws.RetryerV2
requestCloner RequestCloner
}
@ -55,6 +60,10 @@ func NewAttemptMiddleware(retryer aws.Retryer, requestCloner RequestCloner, optF
for _, fn := range optFns {
fn(m)
}
if m.OperationMeter == nil {
m.OperationMeter = metrics.NopMeterProvider{}.Meter("")
}
return m
}
@ -80,6 +89,11 @@ func (r *Attempt) HandleFinalize(ctx context.Context, in smithymiddle.FinalizeIn
maxAttempts := r.retryer.MaxAttempts()
releaseRetryToken := nopRelease
retryMetrics, err := newAttemptMetrics(r.OperationMeter)
if err != nil {
return out, metadata, err
}
for {
attemptNum++
attemptInput := in
@ -97,7 +111,25 @@ func (r *Attempt) HandleFinalize(ctx context.Context, in smithymiddle.FinalizeIn
ctx = internalcontext.SetAttemptSkewContext(ctx, attemptClockSkew)
var attemptResult AttemptResult
attemptCtx, span := tracing.StartSpan(attemptCtx, "Attempt", func(o *tracing.SpanOptions) {
o.Properties.Set("operation.attempt", attemptNum)
})
retryMetrics.Attempts.Add(ctx, 1, withOperationMetadata(ctx))
start := sdk.NowTime()
out, attemptResult, releaseRetryToken, err = r.handleAttempt(attemptCtx, attemptInput, releaseRetryToken, next)
elapsed := sdk.NowTime().Sub(start)
retryMetrics.AttemptDuration.Record(ctx, float64(elapsed)/1e9, withOperationMetadata(ctx))
if err != nil {
retryMetrics.Errors.Add(ctx, 1, withOperationMetadata(ctx), func(o *metrics.RecordMetricOptions) {
o.Properties.Set("exception.type", errorType(err))
})
}
span.End()
attemptClockSkew, _ = awsmiddle.GetAttemptSkew(attemptResult.ResponseMetadata)
// AttemptResult Retried states that the attempt was not successful, and
@ -238,13 +270,6 @@ func (r *Attempt) handleAttempt(
// that time. Potentially early exist if the sleep is canceled via the
// context.
retryDelay, reqErr := r.retryer.RetryDelay(attemptNum, err)
mctx := metrics.Context(ctx)
if mctx != nil {
attempt, err := mctx.Data().LatestAttempt()
if err != nil {
attempt.RetryDelay = retryDelay
}
}
if reqErr != nil {
return out, attemptResult, releaseRetryToken, reqErr
}
@ -381,3 +406,13 @@ func AddRetryMiddlewares(stack *smithymiddle.Stack, options AddRetryMiddlewaresO
}
return nil
}
// Determines the value of exception.type for metrics purposes. We prefer an
// API-specific error code, otherwise it's just the Go type for the value.
func errorType(err error) string {
var terr smithy.APIError
if errors.As(err, &terr) {
return terr.ErrorCode()
}
return fmt.Sprintf("%T", err)
}

View file

@ -45,7 +45,6 @@ var RequiredSignedHeaders = Rules{
"X-Amz-Grant-Write-Acp": struct{}{},
"X-Amz-Metadata-Directive": struct{}{},
"X-Amz-Mfa": struct{}{},
"X-Amz-Request-Payer": struct{}{},
"X-Amz-Server-Side-Encryption": struct{}{},
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
"X-Amz-Server-Side-Encryption-Context": struct{}{},

View file

@ -15,6 +15,7 @@ import (
internalauth "github.com/aws/aws-sdk-go-v2/internal/auth"
"github.com/aws/aws-sdk-go-v2/internal/sdk"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -161,6 +162,9 @@ func (m *ComputePayloadSHA256) HandleFinalize(
return next.HandleFinalize(ctx, in)
}
_, span := tracing.StartSpan(ctx, "ComputePayloadSHA256")
defer span.End()
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &HashComputationError{
@ -186,6 +190,7 @@ func (m *ComputePayloadSHA256) HandleFinalize(
ctx = SetPayloadHash(ctx, hex.EncodeToString(hash.Sum(nil)))
span.End()
return next.HandleFinalize(ctx, in)
}
@ -367,8 +372,9 @@ func GetSignedRequestSignature(r *http.Request) ([]byte, error) {
const authHeaderSignatureElem = "Signature="
if auth := r.Header.Get(authorizationHeader); len(auth) != 0 {
ps := strings.Split(auth, ", ")
ps := strings.Split(auth, ",")
for _, p := range ps {
p = strings.TrimSpace(p)
if idx := strings.Index(p, authHeaderSignatureElem); idx >= 0 {
sig := p[len(authHeaderSignatureElem):]
if len(sig) == 0 {

View file

@ -394,11 +394,16 @@ func (s *httpSigner) buildCredentialScope() string {
func buildQuery(r v4Internal.Rule, header http.Header) (url.Values, http.Header) {
query := url.Values{}
unsignedHeaders := http.Header{}
// A list of headers to be converted to lower case to mitigate a limitation from S3
lowerCaseHeaders := map[string]string{
"X-Amz-Expected-Bucket-Owner": "x-amz-expected-bucket-owner", // see #2508
"X-Amz-Request-Payer": "x-amz-request-payer", // see #2764
}
for k, h := range header {
// literally just this header has this constraint for some stupid reason,
// see #2508
if k == "X-Amz-Expected-Bucket-Owner" {
k = "x-amz-expected-bucket-owner"
if newKey, ok := lowerCaseHeaders[k]; ok {
k = newKey
}
if r.IsValid(k) {

View file

@ -1,13 +1,16 @@
package http
import (
"context"
"crypto/tls"
"github.com/aws/aws-sdk-go-v2/aws"
"net"
"net/http"
"reflect"
"sync"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/smithy-go/tracing"
)
// Defaults for the HTTPTransportBuilder.
@ -179,7 +182,7 @@ func defaultHTTPTransport() *http.Transport {
tr := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialer.DialContext,
DialContext: traceDialContext(dialer.DialContext),
TLSHandshakeTimeout: DefaultHTTPTransportTLSHandleshakeTimeout,
MaxIdleConns: DefaultHTTPTransportMaxIdleConns,
MaxIdleConnsPerHost: DefaultHTTPTransportMaxIdleConnsPerHost,
@ -194,6 +197,35 @@ func defaultHTTPTransport() *http.Transport {
return tr
}
type dialContext func(ctx context.Context, network, addr string) (net.Conn, error)
func traceDialContext(dc dialContext) dialContext {
return func(ctx context.Context, network, addr string) (net.Conn, error) {
span, _ := tracing.GetSpan(ctx)
span.SetProperty("net.peer.name", addr)
conn, err := dc(ctx, network, addr)
if err != nil {
return conn, err
}
raddr := conn.RemoteAddr()
if raddr == nil {
return conn, err
}
host, port, err := net.SplitHostPort(raddr.String())
if err != nil { // don't blow up just because we couldn't parse
span.SetProperty("net.peer.addr", raddr.String())
} else {
span.SetProperty("net.peer.host", host)
span.SetProperty("net.peer.port", port)
}
return conn, err
}
}
// shallowCopyStruct creates a shallow copy of the passed in source struct, and
// returns that copy of the same struct type.
func shallowCopyStruct(src interface{}) interface{} {

View file

@ -1,3 +1,85 @@
# v1.28.7 (2024-12-19)
* **Bug Fix**: Fix improper use of printf-style functions.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.6 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.5 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.4 (2024-11-14)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.3 (2024-11-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.2 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.1 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.0 (2024-10-16)
* **Feature**: Adds the LoadOptions hook `WithBaseEndpoint` for setting global endpoint override in-code.
# v1.27.43 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.42 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.41 (2024-10-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.40 (2024-10-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.39 (2024-09-27)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.38 (2024-09-25)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.37 (2024-09-23)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.36 (2024-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.35 (2024-09-17)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.34 (2024-09-16)
* **Bug Fix**: Read `AWS_CONTAINER_CREDENTIALS_FULL_URI` env variable if set when reading a profile with `credential_source`. Also ensure `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` is always read before it
# v1.27.33 (2024-09-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.32 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.31 (2024-08-26)
* **Dependency Update**: Updated to the latest SDK module versions

View file

@ -3,4 +3,4 @@
package config
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.27.31"
const goModuleVersion = "1.28.7"

View file

@ -217,6 +217,10 @@ type LoadOptions struct {
S3DisableExpressAuth *bool
AccountIDEndpointMode aws.AccountIDEndpointMode
// Service endpoint override. This value is not necessarily final and is
// passed to the service's EndpointResolverV2 for further delegation.
BaseEndpoint string
}
func (o LoadOptions) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) {
@ -284,6 +288,19 @@ func (o LoadOptions) getAccountIDEndpointMode(ctx context.Context) (aws.AccountI
return o.AccountIDEndpointMode, len(o.AccountIDEndpointMode) > 0, nil
}
func (o LoadOptions) getBaseEndpoint(context.Context) (string, bool, error) {
return o.BaseEndpoint, o.BaseEndpoint != "", nil
}
// GetServiceBaseEndpoint satisfies (internal/configsources).ServiceBaseEndpointProvider.
//
// The sdkID value is unused because LoadOptions only supports setting a GLOBAL
// endpoint override. In-code, per-service endpoint overrides are performed via
// functional options in service client space.
func (o LoadOptions) GetServiceBaseEndpoint(context.Context, string) (string, bool, error) {
return o.BaseEndpoint, o.BaseEndpoint != "", nil
}
// WithRegion is a helper function to construct functional options
// that sets Region on config's LoadOptions. Setting the region to
// an empty string, will result in the region value being ignored.
@ -1139,3 +1156,19 @@ func WithS3DisableExpressAuth(v bool) LoadOptionsFunc {
return nil
}
}
// WithBaseEndpoint is a helper function to construct functional options that
// sets BaseEndpoint on config's LoadOptions. Empty values have no effect, and
// subsequent calls to this API override previous ones.
//
// This is an in-code setting, therefore, any value set using this hook takes
// precedence over and will override ALL environment and shared config
// directives that set endpoint URLs. Functional options on service clients
// have higher specificity, and functional options that modify the value of
// BaseEndpoint on a client will take precedence over this setting.
func WithBaseEndpoint(v string) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.BaseEndpoint = v
return nil
}
}

View file

@ -162,12 +162,12 @@ func resolveCredsFromProfile(ctx context.Context, cfg *aws.Config, envConfig *En
// Get credentials from CredentialProcess
err = processCredentials(ctx, cfg, sharedConfig, configs)
case len(envConfig.ContainerCredentialsEndpoint) != 0:
err = resolveLocalHTTPCredProvider(ctx, cfg, envConfig.ContainerCredentialsEndpoint, envConfig.ContainerAuthorizationToken, configs)
case len(envConfig.ContainerCredentialsRelativePath) != 0:
err = resolveHTTPCredProvider(ctx, cfg, ecsContainerURI(envConfig.ContainerCredentialsRelativePath), envConfig.ContainerAuthorizationToken, configs)
case len(envConfig.ContainerCredentialsEndpoint) != 0:
err = resolveLocalHTTPCredProvider(ctx, cfg, envConfig.ContainerCredentialsEndpoint, envConfig.ContainerAuthorizationToken, configs)
default:
err = resolveEC2RoleCredentials(ctx, cfg, configs)
}
@ -355,10 +355,13 @@ func resolveCredsFromSource(ctx context.Context, cfg *aws.Config, envConfig *Env
cfg.Credentials = credentials.StaticCredentialsProvider{Value: envConfig.Credentials}
case credSourceECSContainer:
if len(envConfig.ContainerCredentialsRelativePath) == 0 {
return fmt.Errorf("EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set")
if len(envConfig.ContainerCredentialsRelativePath) != 0 {
return resolveHTTPCredProvider(ctx, cfg, ecsContainerURI(envConfig.ContainerCredentialsRelativePath), envConfig.ContainerAuthorizationToken, configs)
}
return resolveHTTPCredProvider(ctx, cfg, ecsContainerURI(envConfig.ContainerCredentialsRelativePath), envConfig.ContainerAuthorizationToken, configs)
if len(envConfig.ContainerCredentialsEndpoint) != 0 {
return resolveLocalHTTPCredProvider(ctx, cfg, envConfig.ContainerCredentialsEndpoint, envConfig.ContainerAuthorizationToken, configs)
}
return fmt.Errorf("EcsContainer was specified as the credential_source, but neither 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' or AWS_CONTAINER_CREDENTIALS_FULL_URI' was set")
default:
return fmt.Errorf("credential_source values must be EcsContainer, Ec2InstanceMetadata, or Environment")

View file

@ -1,3 +1,77 @@
# v1.17.48 (2024-12-19)
* **Bug Fix**: Fix improper use of printf-style functions.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.47 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.46 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.45 (2024-11-14)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.44 (2024-11-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.43 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.42 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.41 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.40 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.39 (2024-10-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.38 (2024-10-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.37 (2024-09-27)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.36 (2024-09-25)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.35 (2024-09-23)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.34 (2024-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.33 (2024-09-17)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.32 (2024-09-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.31 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.30 (2024-08-26)
* **Bug Fix**: Save SSO cached token expiry in UTC to ensure cross-SDK compatibility.

View file

@ -3,4 +3,4 @@
package credentials
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.17.30"
const goModuleVersion = "1.17.48"

View file

@ -1,3 +1,44 @@
# v1.16.22 (2024-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.21 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.20 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.19 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.18 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.17 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.16 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.15 (2024-10-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.14 (2024-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.13 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.12 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -3,4 +3,4 @@
package imds
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.16.12"
const goModuleVersion = "1.16.22"

View file

@ -1,3 +1,44 @@
# v1.3.26 (2024-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.25 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.24 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.23 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.22 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.21 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.20 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.19 (2024-10-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.18 (2024-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.17 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.3.16 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -3,4 +3,4 @@
package configsources
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.3.16"
const goModuleVersion = "1.3.26"

View file

@ -9,7 +9,7 @@
"supportsDualStack" : true,
"supportsFIPS" : true
},
"regionRegex" : "^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$",
"regionRegex" : "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$",
"regions" : {
"af-south-1" : {
"description" : "Africa (Cape Town)"
@ -44,6 +44,9 @@
"ap-southeast-4" : {
"description" : "Asia Pacific (Melbourne)"
},
"ap-southeast-5" : {
"description" : "Asia Pacific (Malaysia)"
},
"aws-global" : {
"description" : "AWS Standard global region"
},

View file

@ -1,3 +1,45 @@
# v2.6.26 (2024-12-19)
* **Bug Fix**: Fix improper use of printf-style functions.
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.25 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.24 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.23 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.22 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.21 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.20 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.19 (2024-10-04)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.18 (2024-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.17 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v2.6.16 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -3,4 +3,4 @@
package endpoints
// goModuleVersion is the tagged release for this module
const goModuleVersion = "2.6.16"
const goModuleVersion = "2.6.26"

View file

@ -1,3 +1,15 @@
# v1.12.1 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
# v1.12.0 (2024-10-04)
* **Feature**: Add support for HTTP client metrics.
# v1.11.5 (2024-09-20)
* No change notes available for this release.
# v1.11.4 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -3,4 +3,4 @@
package acceptencoding
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.11.4"
const goModuleVersion = "1.12.1"

View file

@ -1,3 +1,45 @@
# v1.12.7 (2024-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.6 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.5 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.4 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.3 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.2 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.1 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.12.0 (2024-10-04)
* **Feature**: Add support for HTTP client metrics.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.11.20 (2024-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.11.19 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.11.18 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -3,4 +3,4 @@
package presignedurl
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.11.18"
const goModuleVersion = "1.12.7"

View file

@ -1,3 +1,74 @@
# v1.24.8 (2024-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.7 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.6 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.5 (2024-11-07)
* **Bug Fix**: Adds case-insensitive handling of error message fields in service responses
# v1.24.4 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.3 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.2 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.1 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.24.0 (2024-10-04)
* **Feature**: Add support for HTTP client metrics.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.23.4 (2024-10-03)
* No change notes available for this release.
# v1.23.3 (2024-09-27)
* No change notes available for this release.
# v1.23.2 (2024-09-25)
* No change notes available for this release.
# v1.23.1 (2024-09-23)
* No change notes available for this release.
# v1.23.0 (2024-09-20)
* **Feature**: Add tracing and metrics support to service clients.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.22.8 (2024-09-17)
* **Bug Fix**: **BREAKFIX**: Only generate AccountIDEndpointMode config for services that use it. This is a compiler break, but removes no actual functionality, as no services currently use the account ID in endpoint resolution.
# v1.22.7 (2024-09-04)
* No change notes available for this release.
# v1.22.6 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.22.5 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -4,6 +4,7 @@ package sso
import (
"context"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/defaults"
@ -19,7 +20,9 @@ import (
smithyauth "github.com/aws/smithy-go/auth"
smithydocument "github.com/aws/smithy-go/document"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net"
"net/http"
@ -30,6 +33,133 @@ import (
const ServiceID = "SSO"
const ServiceAPIVersion = "2019-06-10"
type operationMetrics struct {
Duration metrics.Float64Histogram
SerializeDuration metrics.Float64Histogram
ResolveIdentityDuration metrics.Float64Histogram
ResolveEndpointDuration metrics.Float64Histogram
SignRequestDuration metrics.Float64Histogram
DeserializeDuration metrics.Float64Histogram
}
func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram {
switch name {
case "client.call.duration":
return m.Duration
case "client.call.serialization_duration":
return m.SerializeDuration
case "client.call.resolve_identity_duration":
return m.ResolveIdentityDuration
case "client.call.resolve_endpoint_duration":
return m.ResolveEndpointDuration
case "client.call.signing_duration":
return m.SignRequestDuration
case "client.call.deserialization_duration":
return m.DeserializeDuration
default:
panic("unrecognized operation metric")
}
}
func timeOperationMetric[T any](
ctx context.Context, metric string, fn func() (T, error),
opts ...metrics.RecordMetricOption,
) (T, error) {
instr := getOperationMetrics(ctx).histogramFor(metric)
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
start := time.Now()
v, err := fn()
end := time.Now()
elapsed := end.Sub(start)
instr.Record(ctx, float64(elapsed)/1e9, opts...)
return v, err
}
func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() {
instr := getOperationMetrics(ctx).histogramFor(metric)
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
var ended bool
start := time.Now()
return func() {
if ended {
return
}
ended = true
end := time.Now()
elapsed := end.Sub(start)
instr.Record(ctx, float64(elapsed)/1e9, opts...)
}
}
func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption {
return func(o *metrics.RecordMetricOptions) {
o.Properties.Set("rpc.service", middleware.GetServiceID(ctx))
o.Properties.Set("rpc.method", middleware.GetOperationName(ctx))
}
}
type operationMetricsKey struct{}
func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) {
meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sso")
om := &operationMetrics{}
var err error
om.Duration, err = operationMetricTimer(meter, "client.call.duration",
"Overall call duration (including retries and time to send or receive request and response body)")
if err != nil {
return nil, err
}
om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration",
"The time it takes to serialize a message body")
if err != nil {
return nil, err
}
om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration",
"The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider")
if err != nil {
return nil, err
}
om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration",
"The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request")
if err != nil {
return nil, err
}
om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration",
"The time it takes to sign a request")
if err != nil {
return nil, err
}
om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration",
"The time it takes to deserialize a message body")
if err != nil {
return nil, err
}
return context.WithValue(parent, operationMetricsKey{}, om), nil
}
func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) {
return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = desc
})
}
func getOperationMetrics(ctx context.Context) *operationMetrics {
return ctx.Value(operationMetricsKey{}).(*operationMetrics)
}
func operationTracer(p tracing.TracerProvider) tracing.Tracer {
return p.Tracer("github.com/aws/aws-sdk-go-v2/service/sso")
}
// Client provides the API client to make operations call for AWS Single Sign-On.
type Client struct {
options Options
@ -56,6 +186,10 @@ func New(options Options, optFns ...func(*Options)) *Client {
resolveEndpointResolverV2(&options)
resolveTracerProvider(&options)
resolveMeterProvider(&options)
resolveAuthSchemeResolver(&options)
for _, fn := range optFns {
@ -88,8 +222,15 @@ func (c *Client) Options() Options {
return c.options.Copy()
}
func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) {
func (c *Client) invokeOperation(
ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error,
) (
result interface{}, metadata middleware.Metadata, err error,
) {
ctx = middleware.ClearStackValues(ctx)
ctx = middleware.WithServiceID(ctx, ServiceID)
ctx = middleware.WithOperationName(ctx, opID)
stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
options := c.options.Copy()
@ -113,15 +254,56 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf
}
}
handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
result, metadata, err = handler.Handle(ctx, params)
ctx, err = withOperationMetrics(ctx, options.MeterProvider)
if err != nil {
return nil, metadata, err
}
tracer := operationTracer(options.TracerProvider)
spanName := fmt.Sprintf("%s.%s", ServiceID, opID)
ctx = tracing.WithOperationTracer(ctx, tracer)
ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) {
o.Kind = tracing.SpanKindClient
o.Properties.Set("rpc.system", "aws-api")
o.Properties.Set("rpc.method", opID)
o.Properties.Set("rpc.service", ServiceID)
})
endTimer := startMetricTimer(ctx, "client.call.duration")
defer endTimer()
defer span.End()
handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) {
o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sso")
})
decorated := middleware.DecorateHandler(handler, stack)
result, metadata, err = decorated.Handle(ctx, params)
if err != nil {
span.SetProperty("exception.type", fmt.Sprintf("%T", err))
span.SetProperty("exception.message", err.Error())
var aerr smithy.APIError
if errors.As(err, &aerr) {
span.SetProperty("api.error_code", aerr.ErrorCode())
span.SetProperty("api.error_message", aerr.ErrorMessage())
span.SetProperty("api.error_fault", aerr.ErrorFault().String())
}
err = &smithy.OperationError{
ServiceID: ServiceID,
OperationName: opID,
Err: err,
}
}
span.SetProperty("error", err != nil)
if err == nil {
span.SetStatus(tracing.SpanStatusOK)
} else {
span.SetStatus(tracing.SpanStatusError)
}
return result, metadata, err
}
@ -159,7 +341,7 @@ func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, o
if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil {
return fmt.Errorf("add ResolveEndpointV2: %v", err)
}
if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil {
if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil {
return fmt.Errorf("add Signing: %w", err)
}
return nil
@ -237,16 +419,15 @@ func setResolvedDefaultsMode(o *Options) {
// NewFromConfig returns a new client from the provided config.
func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
opts := Options{
Region: cfg.Region,
DefaultsMode: cfg.DefaultsMode,
RuntimeEnvironment: cfg.RuntimeEnvironment,
HTTPClient: cfg.HTTPClient,
Credentials: cfg.Credentials,
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
AccountIDEndpointMode: cfg.AccountIDEndpointMode,
Region: cfg.Region,
DefaultsMode: cfg.DefaultsMode,
RuntimeEnvironment: cfg.RuntimeEnvironment,
HTTPClient: cfg.HTTPClient,
Credentials: cfg.Credentials,
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
}
resolveAWSRetryerProvider(cfg, &opts)
resolveAWSRetryMaxAttempts(cfg, &opts)
@ -434,6 +615,30 @@ func addRawResponseToMetadata(stack *middleware.Stack) error {
func addRecordResponseTiming(stack *middleware.Stack) error {
return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After)
}
func addSpanRetryLoop(stack *middleware.Stack, options Options) error {
return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before)
}
type spanRetryLoop struct {
options Options
}
func (*spanRetryLoop) ID() string {
return "spanRetryLoop"
}
func (m *spanRetryLoop) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
middleware.FinalizeOutput, middleware.Metadata, error,
) {
tracer := operationTracer(m.options.TracerProvider)
ctx, span := tracer.StartSpan(ctx, "RetryLoop")
defer span.End()
return next.HandleFinalize(ctx, in)
}
func addStreamingEventsPayload(stack *middleware.Stack) error {
return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before)
}
@ -477,6 +682,7 @@ func addIsPaginatorUserAgent(o *Options) {
func addRetry(stack *middleware.Stack, o Options) error {
attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) {
m.LogAttempts = o.ClientLogMode.IsRetries()
m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sso")
})
if err := stack.Finalize.Insert(attempt, "Signing", middleware.Before); err != nil {
return err
@ -540,25 +746,6 @@ func initializeTimeOffsetResolver(c *Client) {
c.timeOffset = new(atomic.Int64)
}
func checkAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) error {
switch mode {
case aws.AccountIDEndpointModeUnset:
case aws.AccountIDEndpointModePreferred:
case aws.AccountIDEndpointModeDisabled:
case aws.AccountIDEndpointModeRequired:
if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); !ok {
return fmt.Errorf("accountID is required but not set")
} else if ca.Credentials.AccountID == "" {
return fmt.Errorf("accountID is required but not set")
}
// default check in case invalid mode is configured through request config
default:
return fmt.Errorf("invalid accountID endpoint mode %s, must be preferred/required/disabled", mode)
}
return nil
}
func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
ua, err := getOrAddRequestUserAgent(stack)
if err != nil {
@ -574,6 +761,18 @@ func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
return nil
}
func resolveTracerProvider(options *Options) {
if options.TracerProvider == nil {
options.TracerProvider = &tracing.NopTracerProvider{}
}
}
func resolveMeterProvider(options *Options) {
if options.MeterProvider == nil {
options.MeterProvider = metrics.NopMeterProvider{}
}
}
func addRecursionDetection(stack *middleware.Stack) error {
return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After)
}
@ -625,3 +824,89 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error {
DisableHTTPS: o.EndpointOptions.DisableHTTPS,
}, "ResolveEndpointV2", middleware.After)
}
type spanInitializeStart struct {
}
func (*spanInitializeStart) ID() string {
return "spanInitializeStart"
}
func (m *spanInitializeStart) HandleInitialize(
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (
middleware.InitializeOutput, middleware.Metadata, error,
) {
ctx, _ = tracing.StartSpan(ctx, "Initialize")
return next.HandleInitialize(ctx, in)
}
type spanInitializeEnd struct {
}
func (*spanInitializeEnd) ID() string {
return "spanInitializeEnd"
}
func (m *spanInitializeEnd) HandleInitialize(
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (
middleware.InitializeOutput, middleware.Metadata, error,
) {
ctx, span := tracing.PopSpan(ctx)
span.End()
return next.HandleInitialize(ctx, in)
}
type spanBuildRequestStart struct {
}
func (*spanBuildRequestStart) ID() string {
return "spanBuildRequestStart"
}
func (m *spanBuildRequestStart) HandleSerialize(
ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler,
) (
middleware.SerializeOutput, middleware.Metadata, error,
) {
ctx, _ = tracing.StartSpan(ctx, "BuildRequest")
return next.HandleSerialize(ctx, in)
}
type spanBuildRequestEnd struct {
}
func (*spanBuildRequestEnd) ID() string {
return "spanBuildRequestEnd"
}
func (m *spanBuildRequestEnd) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
) (
middleware.BuildOutput, middleware.Metadata, error,
) {
ctx, span := tracing.PopSpan(ctx)
span.End()
return next.HandleBuild(ctx, in)
}
func addSpanInitializeStart(stack *middleware.Stack) error {
return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before)
}
func addSpanInitializeEnd(stack *middleware.Stack) error {
return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After)
}
func addSpanBuildRequestStart(stack *middleware.Stack) error {
return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before)
}
func addSpanBuildRequestEnd(stack *middleware.Stack) error {
return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After)
}

View file

@ -102,6 +102,9 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -141,6 +144,18 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -107,6 +107,9 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -146,6 +149,18 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -106,6 +106,9 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -145,6 +148,18 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -101,6 +101,9 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -140,6 +143,18 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -8,7 +8,9 @@ import (
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
smithy "github.com/aws/smithy-go"
smithyauth "github.com/aws/smithy-go/auth"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -169,6 +171,9 @@ func (*resolveAuthSchemeMiddleware) ID() string {
func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
defer span.End()
params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
if err != nil {
@ -181,6 +186,9 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid
}
ctx = setResolvedAuthScheme(ctx, scheme)
span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID())
span.End()
return next.HandleFinalize(ctx, in)
}
@ -240,7 +248,10 @@ func (*getIdentityMiddleware) ID() string {
func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
rscheme := getResolvedAuthScheme(ctx)
innerCtx, span := tracing.StartSpan(ctx, "GetIdentity")
defer span.End()
rscheme := getResolvedAuthScheme(innerCtx)
if rscheme == nil {
return out, metadata, fmt.Errorf("no resolved auth scheme")
}
@ -250,12 +261,20 @@ func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middlewar
return out, metadata, fmt.Errorf("no identity resolver")
}
identity, err := resolver.GetIdentity(ctx, rscheme.IdentityProperties)
identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration",
func() (smithyauth.Identity, error) {
return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties)
},
func(o *metrics.RecordMetricOptions) {
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
})
if err != nil {
return out, metadata, fmt.Errorf("get identity: %w", err)
}
ctx = setIdentity(ctx, identity)
span.End()
return next.HandleFinalize(ctx, in)
}
@ -271,6 +290,7 @@ func getIdentity(ctx context.Context) smithyauth.Identity {
}
type signRequestMiddleware struct {
options Options
}
func (*signRequestMiddleware) ID() string {
@ -280,6 +300,9 @@ func (*signRequestMiddleware) ID() string {
func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "SignRequest")
defer span.End()
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request)
@ -300,9 +323,15 @@ func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middlewar
return out, metadata, fmt.Errorf("no signer")
}
if err := signer.SignRequest(ctx, req, identity, rscheme.SignerProperties); err != nil {
_, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) {
return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties)
}, func(o *metrics.RecordMetricOptions) {
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
})
if err != nil {
return out, metadata, fmt.Errorf("sign request: %w", err)
}
span.End()
return next.HandleFinalize(ctx, in)
}

View file

@ -14,6 +14,7 @@ import (
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/ptr"
smithytime "github.com/aws/smithy-go/time"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"io"
"io/ioutil"
@ -44,6 +45,10 @@ func (m *awsRestjson1_deserializeOpGetRoleCredentials) HandleDeserialize(ctx con
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -83,6 +88,7 @@ func (m *awsRestjson1_deserializeOpGetRoleCredentials) HandleDeserialize(ctx con
}
}
span.End()
return out, metadata, err
}
@ -200,6 +206,10 @@ func (m *awsRestjson1_deserializeOpListAccountRoles) HandleDeserialize(ctx conte
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -239,6 +249,7 @@ func (m *awsRestjson1_deserializeOpListAccountRoles) HandleDeserialize(ctx conte
}
}
span.End()
return out, metadata, err
}
@ -365,6 +376,10 @@ func (m *awsRestjson1_deserializeOpListAccounts) HandleDeserialize(ctx context.C
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -404,6 +419,7 @@ func (m *awsRestjson1_deserializeOpListAccounts) HandleDeserialize(ctx context.C
}
}
span.End()
return out, metadata, err
}
@ -530,6 +546,10 @@ func (m *awsRestjson1_deserializeOpLogout) HandleDeserialize(ctx context.Context
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -547,6 +567,7 @@ func (m *awsRestjson1_deserializeOpLogout) HandleDeserialize(ctx context.Context
}
}
span.End()
return out, metadata, err
}
@ -868,7 +889,7 @@ func awsRestjson1_deserializeDocumentInvalidRequestException(v **types.InvalidRe
for key, value := range shape {
switch key {
case "message":
case "message", "Message":
if value != nil {
jtv, ok := value.(string)
if !ok {
@ -908,7 +929,7 @@ func awsRestjson1_deserializeDocumentResourceNotFoundException(v **types.Resourc
for key, value := range shape {
switch key {
case "message":
case "message", "Message":
if value != nil {
jtv, ok := value.(string)
if !ok {
@ -1102,7 +1123,7 @@ func awsRestjson1_deserializeDocumentTooManyRequestsException(v **types.TooManyR
for key, value := range shape {
switch key {
case "message":
case "message", "Message":
if value != nil {
jtv, ok := value.(string)
if !ok {
@ -1142,7 +1163,7 @@ func awsRestjson1_deserializeDocumentUnauthorizedException(v **types.Unauthorize
for key, value := range shape {
switch key {
case "message":
case "message", "Message":
if value != nil {
jtv, ok := value.(string)
if !ok {

View file

@ -16,6 +16,7 @@ import (
smithyendpoints "github.com/aws/smithy-go/endpoints"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/ptr"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net/http"
"net/url"
@ -502,14 +503,13 @@ func (*resolveEndpointV2Middleware) ID() string {
func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "ResolveEndpoint")
defer span.End()
if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
return next.HandleFinalize(ctx, in)
}
if err := checkAccountID(getIdentity(ctx), m.options.AccountIDEndpointMode); err != nil {
return out, metadata, fmt.Errorf("invalid accountID set: %w", err)
}
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
@ -520,11 +520,16 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid
}
params := bindEndpointParams(ctx, getOperationInput(ctx), m.options)
endpt, err := m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration",
func() (smithyendpoints.Endpoint, error) {
return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
})
if err != nil {
return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
}
span.SetProperty("client.call.resolved_endpoint", endpt.URI.String())
if endpt.URI.RawPath == "" && req.URL.RawPath != "" {
endpt.URI.RawPath = endpt.URI.Path
}
@ -546,5 +551,6 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid
rscheme.SignerProperties.SetAll(&o.SignerProperties)
}
span.End()
return next.HandleFinalize(ctx, in)
}

View file

@ -3,4 +3,4 @@
package sso
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.22.5"
const goModuleVersion = "1.24.8"

View file

@ -94,7 +94,7 @@ var partitionRegexp = struct {
AwsUsGov *regexp.Regexp
}{
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"),
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"),
AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"),
AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"),
AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"),

View file

@ -9,7 +9,9 @@ import (
internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy"
smithyauth "github.com/aws/smithy-go/auth"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net/http"
)
@ -24,9 +26,6 @@ type Options struct {
// modify this list for per operation behavior.
APIOptions []func(*middleware.Stack) error
// Indicates how aws account ID is applied in endpoint2.0 routing
AccountIDEndpointMode aws.AccountIDEndpointMode
// The optional application specific identifier appended to the User-Agent header.
AppID string
@ -69,6 +68,9 @@ type Options struct {
// The logger writer interface to write logging messages to.
Logger logging.Logger
// The client meter provider.
MeterProvider metrics.MeterProvider
// The region to send requests to. (Required)
Region string
@ -103,6 +105,9 @@ type Options struct {
// within your applications.
RuntimeEnvironment aws.RuntimeEnvironment
// The client tracer provider.
TracerProvider tracing.TracerProvider
// The initial DefaultsMode used when the client options were constructed. If the
// DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved
// value was at that point in time.

View file

@ -8,6 +8,7 @@ import (
smithy "github.com/aws/smithy-go"
"github.com/aws/smithy-go/encoding/httpbinding"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -21,6 +22,10 @@ func (*awsRestjson1_serializeOpGetRoleCredentials) ID() string {
func (m *awsRestjson1_serializeOpGetRoleCredentials) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -57,6 +62,8 @@ func (m *awsRestjson1_serializeOpGetRoleCredentials) HandleSerialize(ctx context
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsGetRoleCredentialsInput(v *GetRoleCredentialsInput, encoder *httpbinding.Encoder) error {
@ -64,7 +71,7 @@ func awsRestjson1_serializeOpHttpBindingsGetRoleCredentialsInput(v *GetRoleCrede
return fmt.Errorf("unsupported serialization of nil %T", v)
}
if v.AccessToken != nil && len(*v.AccessToken) > 0 {
if v.AccessToken != nil {
locationName := "X-Amz-Sso_bearer_token"
encoder.SetHeader(locationName).String(*v.AccessToken)
}
@ -90,6 +97,10 @@ func (*awsRestjson1_serializeOpListAccountRoles) ID() string {
func (m *awsRestjson1_serializeOpListAccountRoles) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -126,6 +137,8 @@ func (m *awsRestjson1_serializeOpListAccountRoles) HandleSerialize(ctx context.C
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsListAccountRolesInput(v *ListAccountRolesInput, encoder *httpbinding.Encoder) error {
@ -133,7 +146,7 @@ func awsRestjson1_serializeOpHttpBindingsListAccountRolesInput(v *ListAccountRol
return fmt.Errorf("unsupported serialization of nil %T", v)
}
if v.AccessToken != nil && len(*v.AccessToken) > 0 {
if v.AccessToken != nil {
locationName := "X-Amz-Sso_bearer_token"
encoder.SetHeader(locationName).String(*v.AccessToken)
}
@ -163,6 +176,10 @@ func (*awsRestjson1_serializeOpListAccounts) ID() string {
func (m *awsRestjson1_serializeOpListAccounts) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -199,6 +216,8 @@ func (m *awsRestjson1_serializeOpListAccounts) HandleSerialize(ctx context.Conte
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsListAccountsInput(v *ListAccountsInput, encoder *httpbinding.Encoder) error {
@ -206,7 +225,7 @@ func awsRestjson1_serializeOpHttpBindingsListAccountsInput(v *ListAccountsInput,
return fmt.Errorf("unsupported serialization of nil %T", v)
}
if v.AccessToken != nil && len(*v.AccessToken) > 0 {
if v.AccessToken != nil {
locationName := "X-Amz-Sso_bearer_token"
encoder.SetHeader(locationName).String(*v.AccessToken)
}
@ -232,6 +251,10 @@ func (*awsRestjson1_serializeOpLogout) ID() string {
func (m *awsRestjson1_serializeOpLogout) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -268,6 +291,8 @@ func (m *awsRestjson1_serializeOpLogout) HandleSerialize(ctx context.Context, in
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsLogoutInput(v *LogoutInput, encoder *httpbinding.Encoder) error {
@ -275,7 +300,7 @@ func awsRestjson1_serializeOpHttpBindingsLogoutInput(v *LogoutInput, encoder *ht
return fmt.Errorf("unsupported serialization of nil %T", v)
}
if v.AccessToken != nil && len(*v.AccessToken) > 0 {
if v.AccessToken != nil {
locationName := "X-Amz-Sso_bearer_token"
encoder.SetHeader(locationName).String(*v.AccessToken)
}

View file

@ -1,3 +1,70 @@
# v1.28.7 (2024-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.6 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.5 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.4 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.3 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.2 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.1 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.28.0 (2024-10-04)
* **Feature**: Add support for HTTP client metrics.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.27.4 (2024-10-03)
* No change notes available for this release.
# v1.27.3 (2024-09-27)
* No change notes available for this release.
# v1.27.2 (2024-09-25)
* No change notes available for this release.
# v1.27.1 (2024-09-23)
* No change notes available for this release.
# v1.27.0 (2024-09-20)
* **Feature**: Add tracing and metrics support to service clients.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.26.8 (2024-09-17)
* **Bug Fix**: **BREAKFIX**: Only generate AccountIDEndpointMode config for services that use it. This is a compiler break, but removes no actual functionality, as no services currently use the account ID in endpoint resolution.
# v1.26.7 (2024-09-04)
* No change notes available for this release.
# v1.26.6 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.26.5 (2024-08-15)
* **Dependency Update**: Bump minimum Go version to 1.21.

View file

@ -4,6 +4,7 @@ package ssooidc
import (
"context"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/defaults"
@ -19,7 +20,9 @@ import (
smithyauth "github.com/aws/smithy-go/auth"
smithydocument "github.com/aws/smithy-go/document"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net"
"net/http"
@ -30,6 +33,133 @@ import (
const ServiceID = "SSO OIDC"
const ServiceAPIVersion = "2019-06-10"
type operationMetrics struct {
Duration metrics.Float64Histogram
SerializeDuration metrics.Float64Histogram
ResolveIdentityDuration metrics.Float64Histogram
ResolveEndpointDuration metrics.Float64Histogram
SignRequestDuration metrics.Float64Histogram
DeserializeDuration metrics.Float64Histogram
}
func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram {
switch name {
case "client.call.duration":
return m.Duration
case "client.call.serialization_duration":
return m.SerializeDuration
case "client.call.resolve_identity_duration":
return m.ResolveIdentityDuration
case "client.call.resolve_endpoint_duration":
return m.ResolveEndpointDuration
case "client.call.signing_duration":
return m.SignRequestDuration
case "client.call.deserialization_duration":
return m.DeserializeDuration
default:
panic("unrecognized operation metric")
}
}
func timeOperationMetric[T any](
ctx context.Context, metric string, fn func() (T, error),
opts ...metrics.RecordMetricOption,
) (T, error) {
instr := getOperationMetrics(ctx).histogramFor(metric)
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
start := time.Now()
v, err := fn()
end := time.Now()
elapsed := end.Sub(start)
instr.Record(ctx, float64(elapsed)/1e9, opts...)
return v, err
}
func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() {
instr := getOperationMetrics(ctx).histogramFor(metric)
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
var ended bool
start := time.Now()
return func() {
if ended {
return
}
ended = true
end := time.Now()
elapsed := end.Sub(start)
instr.Record(ctx, float64(elapsed)/1e9, opts...)
}
}
func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption {
return func(o *metrics.RecordMetricOptions) {
o.Properties.Set("rpc.service", middleware.GetServiceID(ctx))
o.Properties.Set("rpc.method", middleware.GetOperationName(ctx))
}
}
type operationMetricsKey struct{}
func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) {
meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc")
om := &operationMetrics{}
var err error
om.Duration, err = operationMetricTimer(meter, "client.call.duration",
"Overall call duration (including retries and time to send or receive request and response body)")
if err != nil {
return nil, err
}
om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration",
"The time it takes to serialize a message body")
if err != nil {
return nil, err
}
om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration",
"The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider")
if err != nil {
return nil, err
}
om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration",
"The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request")
if err != nil {
return nil, err
}
om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration",
"The time it takes to sign a request")
if err != nil {
return nil, err
}
om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration",
"The time it takes to deserialize a message body")
if err != nil {
return nil, err
}
return context.WithValue(parent, operationMetricsKey{}, om), nil
}
func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) {
return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = desc
})
}
func getOperationMetrics(ctx context.Context) *operationMetrics {
return ctx.Value(operationMetricsKey{}).(*operationMetrics)
}
func operationTracer(p tracing.TracerProvider) tracing.Tracer {
return p.Tracer("github.com/aws/aws-sdk-go-v2/service/ssooidc")
}
// Client provides the API client to make operations call for AWS SSO OIDC.
type Client struct {
options Options
@ -56,6 +186,10 @@ func New(options Options, optFns ...func(*Options)) *Client {
resolveEndpointResolverV2(&options)
resolveTracerProvider(&options)
resolveMeterProvider(&options)
resolveAuthSchemeResolver(&options)
for _, fn := range optFns {
@ -88,8 +222,15 @@ func (c *Client) Options() Options {
return c.options.Copy()
}
func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) {
func (c *Client) invokeOperation(
ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error,
) (
result interface{}, metadata middleware.Metadata, err error,
) {
ctx = middleware.ClearStackValues(ctx)
ctx = middleware.WithServiceID(ctx, ServiceID)
ctx = middleware.WithOperationName(ctx, opID)
stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
options := c.options.Copy()
@ -113,15 +254,56 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf
}
}
handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
result, metadata, err = handler.Handle(ctx, params)
ctx, err = withOperationMetrics(ctx, options.MeterProvider)
if err != nil {
return nil, metadata, err
}
tracer := operationTracer(options.TracerProvider)
spanName := fmt.Sprintf("%s.%s", ServiceID, opID)
ctx = tracing.WithOperationTracer(ctx, tracer)
ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) {
o.Kind = tracing.SpanKindClient
o.Properties.Set("rpc.system", "aws-api")
o.Properties.Set("rpc.method", opID)
o.Properties.Set("rpc.service", ServiceID)
})
endTimer := startMetricTimer(ctx, "client.call.duration")
defer endTimer()
defer span.End()
handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) {
o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc")
})
decorated := middleware.DecorateHandler(handler, stack)
result, metadata, err = decorated.Handle(ctx, params)
if err != nil {
span.SetProperty("exception.type", fmt.Sprintf("%T", err))
span.SetProperty("exception.message", err.Error())
var aerr smithy.APIError
if errors.As(err, &aerr) {
span.SetProperty("api.error_code", aerr.ErrorCode())
span.SetProperty("api.error_message", aerr.ErrorMessage())
span.SetProperty("api.error_fault", aerr.ErrorFault().String())
}
err = &smithy.OperationError{
ServiceID: ServiceID,
OperationName: opID,
Err: err,
}
}
span.SetProperty("error", err != nil)
if err == nil {
span.SetStatus(tracing.SpanStatusOK)
} else {
span.SetStatus(tracing.SpanStatusError)
}
return result, metadata, err
}
@ -159,7 +341,7 @@ func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, o
if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil {
return fmt.Errorf("add ResolveEndpointV2: %v", err)
}
if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil {
if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil {
return fmt.Errorf("add Signing: %w", err)
}
return nil
@ -237,16 +419,15 @@ func setResolvedDefaultsMode(o *Options) {
// NewFromConfig returns a new client from the provided config.
func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
opts := Options{
Region: cfg.Region,
DefaultsMode: cfg.DefaultsMode,
RuntimeEnvironment: cfg.RuntimeEnvironment,
HTTPClient: cfg.HTTPClient,
Credentials: cfg.Credentials,
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
AccountIDEndpointMode: cfg.AccountIDEndpointMode,
Region: cfg.Region,
DefaultsMode: cfg.DefaultsMode,
RuntimeEnvironment: cfg.RuntimeEnvironment,
HTTPClient: cfg.HTTPClient,
Credentials: cfg.Credentials,
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
}
resolveAWSRetryerProvider(cfg, &opts)
resolveAWSRetryMaxAttempts(cfg, &opts)
@ -434,6 +615,30 @@ func addRawResponseToMetadata(stack *middleware.Stack) error {
func addRecordResponseTiming(stack *middleware.Stack) error {
return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After)
}
func addSpanRetryLoop(stack *middleware.Stack, options Options) error {
return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before)
}
type spanRetryLoop struct {
options Options
}
func (*spanRetryLoop) ID() string {
return "spanRetryLoop"
}
func (m *spanRetryLoop) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
middleware.FinalizeOutput, middleware.Metadata, error,
) {
tracer := operationTracer(m.options.TracerProvider)
ctx, span := tracer.StartSpan(ctx, "RetryLoop")
defer span.End()
return next.HandleFinalize(ctx, in)
}
func addStreamingEventsPayload(stack *middleware.Stack) error {
return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before)
}
@ -477,6 +682,7 @@ func addIsPaginatorUserAgent(o *Options) {
func addRetry(stack *middleware.Stack, o Options) error {
attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) {
m.LogAttempts = o.ClientLogMode.IsRetries()
m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc")
})
if err := stack.Finalize.Insert(attempt, "Signing", middleware.Before); err != nil {
return err
@ -540,25 +746,6 @@ func initializeTimeOffsetResolver(c *Client) {
c.timeOffset = new(atomic.Int64)
}
func checkAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) error {
switch mode {
case aws.AccountIDEndpointModeUnset:
case aws.AccountIDEndpointModePreferred:
case aws.AccountIDEndpointModeDisabled:
case aws.AccountIDEndpointModeRequired:
if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); !ok {
return fmt.Errorf("accountID is required but not set")
} else if ca.Credentials.AccountID == "" {
return fmt.Errorf("accountID is required but not set")
}
// default check in case invalid mode is configured through request config
default:
return fmt.Errorf("invalid accountID endpoint mode %s, must be preferred/required/disabled", mode)
}
return nil
}
func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
ua, err := getOrAddRequestUserAgent(stack)
if err != nil {
@ -574,6 +761,18 @@ func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
return nil
}
func resolveTracerProvider(options *Options) {
if options.TracerProvider == nil {
options.TracerProvider = &tracing.NopTracerProvider{}
}
}
func resolveMeterProvider(options *Options) {
if options.MeterProvider == nil {
options.MeterProvider = metrics.NopMeterProvider{}
}
}
func addRecursionDetection(stack *middleware.Stack) error {
return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After)
}
@ -625,3 +824,89 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error {
DisableHTTPS: o.EndpointOptions.DisableHTTPS,
}, "ResolveEndpointV2", middleware.After)
}
type spanInitializeStart struct {
}
func (*spanInitializeStart) ID() string {
return "spanInitializeStart"
}
func (m *spanInitializeStart) HandleInitialize(
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (
middleware.InitializeOutput, middleware.Metadata, error,
) {
ctx, _ = tracing.StartSpan(ctx, "Initialize")
return next.HandleInitialize(ctx, in)
}
type spanInitializeEnd struct {
}
func (*spanInitializeEnd) ID() string {
return "spanInitializeEnd"
}
func (m *spanInitializeEnd) HandleInitialize(
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (
middleware.InitializeOutput, middleware.Metadata, error,
) {
ctx, span := tracing.PopSpan(ctx)
span.End()
return next.HandleInitialize(ctx, in)
}
type spanBuildRequestStart struct {
}
func (*spanBuildRequestStart) ID() string {
return "spanBuildRequestStart"
}
func (m *spanBuildRequestStart) HandleSerialize(
ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler,
) (
middleware.SerializeOutput, middleware.Metadata, error,
) {
ctx, _ = tracing.StartSpan(ctx, "BuildRequest")
return next.HandleSerialize(ctx, in)
}
type spanBuildRequestEnd struct {
}
func (*spanBuildRequestEnd) ID() string {
return "spanBuildRequestEnd"
}
func (m *spanBuildRequestEnd) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
) (
middleware.BuildOutput, middleware.Metadata, error,
) {
ctx, span := tracing.PopSpan(ctx)
span.End()
return next.HandleBuild(ctx, in)
}
func addSpanInitializeStart(stack *middleware.Stack) error {
return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before)
}
func addSpanInitializeEnd(stack *middleware.Stack) error {
return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After)
}
func addSpanBuildRequestStart(stack *middleware.Stack) error {
return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before)
}
func addSpanBuildRequestEnd(stack *middleware.Stack) error {
return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After)
}

View file

@ -174,6 +174,9 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -213,6 +216,18 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -205,6 +205,9 @@ func (c *Client) addOperationCreateTokenWithIAMMiddlewares(stack *middleware.Sta
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -244,6 +247,18 @@ func (c *Client) addOperationCreateTokenWithIAMMiddlewares(stack *middleware.Sta
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -135,6 +135,9 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack,
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -174,6 +177,18 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack,
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -125,6 +125,9 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -164,6 +167,18 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -8,7 +8,9 @@ import (
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
smithy "github.com/aws/smithy-go"
smithyauth "github.com/aws/smithy-go/auth"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -163,6 +165,9 @@ func (*resolveAuthSchemeMiddleware) ID() string {
func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
defer span.End()
params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
if err != nil {
@ -175,6 +180,9 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid
}
ctx = setResolvedAuthScheme(ctx, scheme)
span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID())
span.End()
return next.HandleFinalize(ctx, in)
}
@ -234,7 +242,10 @@ func (*getIdentityMiddleware) ID() string {
func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
rscheme := getResolvedAuthScheme(ctx)
innerCtx, span := tracing.StartSpan(ctx, "GetIdentity")
defer span.End()
rscheme := getResolvedAuthScheme(innerCtx)
if rscheme == nil {
return out, metadata, fmt.Errorf("no resolved auth scheme")
}
@ -244,12 +255,20 @@ func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middlewar
return out, metadata, fmt.Errorf("no identity resolver")
}
identity, err := resolver.GetIdentity(ctx, rscheme.IdentityProperties)
identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration",
func() (smithyauth.Identity, error) {
return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties)
},
func(o *metrics.RecordMetricOptions) {
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
})
if err != nil {
return out, metadata, fmt.Errorf("get identity: %w", err)
}
ctx = setIdentity(ctx, identity)
span.End()
return next.HandleFinalize(ctx, in)
}
@ -265,6 +284,7 @@ func getIdentity(ctx context.Context) smithyauth.Identity {
}
type signRequestMiddleware struct {
options Options
}
func (*signRequestMiddleware) ID() string {
@ -274,6 +294,9 @@ func (*signRequestMiddleware) ID() string {
func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "SignRequest")
defer span.End()
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request)
@ -294,9 +317,15 @@ func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middlewar
return out, metadata, fmt.Errorf("no signer")
}
if err := signer.SignRequest(ctx, req, identity, rscheme.SignerProperties); err != nil {
_, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) {
return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties)
}, func(o *metrics.RecordMetricOptions) {
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
})
if err != nil {
return out, metadata, fmt.Errorf("sign request: %w", err)
}
span.End()
return next.HandleFinalize(ctx, in)
}

View file

@ -14,6 +14,7 @@ import (
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/ptr"
smithytime "github.com/aws/smithy-go/time"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"io"
"strings"
@ -43,6 +44,10 @@ func (m *awsRestjson1_deserializeOpCreateToken) HandleDeserialize(ctx context.Co
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -82,6 +87,7 @@ func (m *awsRestjson1_deserializeOpCreateToken) HandleDeserialize(ctx context.Co
}
}
span.End()
return out, metadata, err
}
@ -264,6 +270,10 @@ func (m *awsRestjson1_deserializeOpCreateTokenWithIAM) HandleDeserialize(ctx con
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -303,6 +313,7 @@ func (m *awsRestjson1_deserializeOpCreateTokenWithIAM) HandleDeserialize(ctx con
}
}
span.End()
return out, metadata, err
}
@ -502,6 +513,10 @@ func (m *awsRestjson1_deserializeOpRegisterClient) HandleDeserialize(ctx context
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -541,6 +556,7 @@ func (m *awsRestjson1_deserializeOpRegisterClient) HandleDeserialize(ctx context
}
}
span.End()
return out, metadata, err
}
@ -721,6 +737,10 @@ func (m *awsRestjson1_deserializeOpStartDeviceAuthorization) HandleDeserialize(c
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -760,6 +780,7 @@ func (m *awsRestjson1_deserializeOpStartDeviceAuthorization) HandleDeserialize(c
}
}
span.End()
return out, metadata, err
}

View file

@ -16,6 +16,7 @@ import (
smithyendpoints "github.com/aws/smithy-go/endpoints"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/ptr"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net/http"
"net/url"
@ -502,14 +503,13 @@ func (*resolveEndpointV2Middleware) ID() string {
func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "ResolveEndpoint")
defer span.End()
if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
return next.HandleFinalize(ctx, in)
}
if err := checkAccountID(getIdentity(ctx), m.options.AccountIDEndpointMode); err != nil {
return out, metadata, fmt.Errorf("invalid accountID set: %w", err)
}
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
@ -520,11 +520,16 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid
}
params := bindEndpointParams(ctx, getOperationInput(ctx), m.options)
endpt, err := m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration",
func() (smithyendpoints.Endpoint, error) {
return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
})
if err != nil {
return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
}
span.SetProperty("client.call.resolved_endpoint", endpt.URI.String())
if endpt.URI.RawPath == "" && req.URL.RawPath != "" {
endpt.URI.RawPath = endpt.URI.Path
}
@ -546,5 +551,6 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid
rscheme.SignerProperties.SetAll(&o.SignerProperties)
}
span.End()
return next.HandleFinalize(ctx, in)
}

View file

@ -3,4 +3,4 @@
package ssooidc
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.26.5"
const goModuleVersion = "1.28.7"

View file

@ -94,7 +94,7 @@ var partitionRegexp = struct {
AwsUsGov *regexp.Regexp
}{
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"),
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"),
AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"),
AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"),
AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"),

View file

@ -9,7 +9,9 @@ import (
internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy"
smithyauth "github.com/aws/smithy-go/auth"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net/http"
)
@ -24,9 +26,6 @@ type Options struct {
// modify this list for per operation behavior.
APIOptions []func(*middleware.Stack) error
// Indicates how aws account ID is applied in endpoint2.0 routing
AccountIDEndpointMode aws.AccountIDEndpointMode
// The optional application specific identifier appended to the User-Agent header.
AppID string
@ -69,6 +68,9 @@ type Options struct {
// The logger writer interface to write logging messages to.
Logger logging.Logger
// The client meter provider.
MeterProvider metrics.MeterProvider
// The region to send requests to. (Required)
Region string
@ -103,6 +105,9 @@ type Options struct {
// within your applications.
RuntimeEnvironment aws.RuntimeEnvironment
// The client tracer provider.
TracerProvider tracing.TracerProvider
// The initial DefaultsMode used when the client options were constructed. If the
// DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved
// value was at that point in time.

View file

@ -10,6 +10,7 @@ import (
"github.com/aws/smithy-go/encoding/httpbinding"
smithyjson "github.com/aws/smithy-go/encoding/json"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -23,6 +24,10 @@ func (*awsRestjson1_serializeOpCreateToken) ID() string {
func (m *awsRestjson1_serializeOpCreateToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -66,6 +71,8 @@ func (m *awsRestjson1_serializeOpCreateToken) HandleSerialize(ctx context.Contex
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsCreateTokenInput(v *CreateTokenInput, encoder *httpbinding.Encoder) error {
@ -140,6 +147,10 @@ func (*awsRestjson1_serializeOpCreateTokenWithIAM) ID() string {
func (m *awsRestjson1_serializeOpCreateTokenWithIAM) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -183,6 +194,8 @@ func (m *awsRestjson1_serializeOpCreateTokenWithIAM) HandleSerialize(ctx context
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsCreateTokenWithIAMInput(v *CreateTokenWithIAMInput, encoder *httpbinding.Encoder) error {
@ -267,6 +280,10 @@ func (*awsRestjson1_serializeOpRegisterClient) ID() string {
func (m *awsRestjson1_serializeOpRegisterClient) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -310,6 +327,8 @@ func (m *awsRestjson1_serializeOpRegisterClient) HandleSerialize(ctx context.Con
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsRegisterClientInput(v *RegisterClientInput, encoder *httpbinding.Encoder) error {
@ -378,6 +397,10 @@ func (*awsRestjson1_serializeOpStartDeviceAuthorization) ID() string {
func (m *awsRestjson1_serializeOpStartDeviceAuthorization) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -421,6 +444,8 @@ func (m *awsRestjson1_serializeOpStartDeviceAuthorization) HandleSerialize(ctx c
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsRestjson1_serializeOpHttpBindingsStartDeviceAuthorizationInput(v *StartDeviceAuthorizationInput, encoder *httpbinding.Encoder) error {

View file

@ -1,3 +1,74 @@
# v1.33.3 (2024-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.33.2 (2024-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.33.1 (2024-11-18)
* **Dependency Update**: Update to smithy-go v1.22.1.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.33.0 (2024-11-14)
* **Feature**: This release introduces the new API 'AssumeRoot', which returns short-term credentials that you can use to perform privileged tasks.
# v1.32.4 (2024-11-06)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.32.3 (2024-10-28)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.32.2 (2024-10-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.32.1 (2024-10-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.32.0 (2024-10-04)
* **Feature**: Add support for HTTP client metrics.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.31.4 (2024-10-03)
* No change notes available for this release.
# v1.31.3 (2024-09-27)
* No change notes available for this release.
# v1.31.2 (2024-09-25)
* No change notes available for this release.
# v1.31.1 (2024-09-23)
* No change notes available for this release.
# v1.31.0 (2024-09-20)
* **Feature**: Add tracing and metrics support to service clients.
* **Dependency Update**: Updated to the latest SDK module versions
# v1.30.8 (2024-09-17)
* **Bug Fix**: **BREAKFIX**: Only generate AccountIDEndpointMode config for services that use it. This is a compiler break, but removes no actual functionality, as no services currently use the account ID in endpoint resolution.
# v1.30.7 (2024-09-04)
* No change notes available for this release.
# v1.30.6 (2024-09-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.30.5 (2024-08-22)
* No change notes available for this release.

View file

@ -4,6 +4,7 @@ package sts
import (
"context"
"errors"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/defaults"
@ -22,7 +23,9 @@ import (
smithyauth "github.com/aws/smithy-go/auth"
smithydocument "github.com/aws/smithy-go/document"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net"
"net/http"
@ -33,6 +36,133 @@ import (
const ServiceID = "STS"
const ServiceAPIVersion = "2011-06-15"
type operationMetrics struct {
Duration metrics.Float64Histogram
SerializeDuration metrics.Float64Histogram
ResolveIdentityDuration metrics.Float64Histogram
ResolveEndpointDuration metrics.Float64Histogram
SignRequestDuration metrics.Float64Histogram
DeserializeDuration metrics.Float64Histogram
}
func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram {
switch name {
case "client.call.duration":
return m.Duration
case "client.call.serialization_duration":
return m.SerializeDuration
case "client.call.resolve_identity_duration":
return m.ResolveIdentityDuration
case "client.call.resolve_endpoint_duration":
return m.ResolveEndpointDuration
case "client.call.signing_duration":
return m.SignRequestDuration
case "client.call.deserialization_duration":
return m.DeserializeDuration
default:
panic("unrecognized operation metric")
}
}
func timeOperationMetric[T any](
ctx context.Context, metric string, fn func() (T, error),
opts ...metrics.RecordMetricOption,
) (T, error) {
instr := getOperationMetrics(ctx).histogramFor(metric)
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
start := time.Now()
v, err := fn()
end := time.Now()
elapsed := end.Sub(start)
instr.Record(ctx, float64(elapsed)/1e9, opts...)
return v, err
}
func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() {
instr := getOperationMetrics(ctx).histogramFor(metric)
opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...)
var ended bool
start := time.Now()
return func() {
if ended {
return
}
ended = true
end := time.Now()
elapsed := end.Sub(start)
instr.Record(ctx, float64(elapsed)/1e9, opts...)
}
}
func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption {
return func(o *metrics.RecordMetricOptions) {
o.Properties.Set("rpc.service", middleware.GetServiceID(ctx))
o.Properties.Set("rpc.method", middleware.GetOperationName(ctx))
}
}
type operationMetricsKey struct{}
func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) {
meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sts")
om := &operationMetrics{}
var err error
om.Duration, err = operationMetricTimer(meter, "client.call.duration",
"Overall call duration (including retries and time to send or receive request and response body)")
if err != nil {
return nil, err
}
om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration",
"The time it takes to serialize a message body")
if err != nil {
return nil, err
}
om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration",
"The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider")
if err != nil {
return nil, err
}
om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration",
"The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request")
if err != nil {
return nil, err
}
om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration",
"The time it takes to sign a request")
if err != nil {
return nil, err
}
om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration",
"The time it takes to deserialize a message body")
if err != nil {
return nil, err
}
return context.WithValue(parent, operationMetricsKey{}, om), nil
}
func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) {
return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = desc
})
}
func getOperationMetrics(ctx context.Context) *operationMetrics {
return ctx.Value(operationMetricsKey{}).(*operationMetrics)
}
func operationTracer(p tracing.TracerProvider) tracing.Tracer {
return p.Tracer("github.com/aws/aws-sdk-go-v2/service/sts")
}
// Client provides the API client to make operations call for AWS Security Token
// Service.
type Client struct {
@ -60,6 +190,10 @@ func New(options Options, optFns ...func(*Options)) *Client {
resolveEndpointResolverV2(&options)
resolveTracerProvider(&options)
resolveMeterProvider(&options)
resolveAuthSchemeResolver(&options)
for _, fn := range optFns {
@ -92,8 +226,15 @@ func (c *Client) Options() Options {
return c.options.Copy()
}
func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) {
func (c *Client) invokeOperation(
ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error,
) (
result interface{}, metadata middleware.Metadata, err error,
) {
ctx = middleware.ClearStackValues(ctx)
ctx = middleware.WithServiceID(ctx, ServiceID)
ctx = middleware.WithOperationName(ctx, opID)
stack := middleware.NewStack(opID, smithyhttp.NewStackRequest)
options := c.options.Copy()
@ -117,15 +258,56 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf
}
}
handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
result, metadata, err = handler.Handle(ctx, params)
ctx, err = withOperationMetrics(ctx, options.MeterProvider)
if err != nil {
return nil, metadata, err
}
tracer := operationTracer(options.TracerProvider)
spanName := fmt.Sprintf("%s.%s", ServiceID, opID)
ctx = tracing.WithOperationTracer(ctx, tracer)
ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) {
o.Kind = tracing.SpanKindClient
o.Properties.Set("rpc.system", "aws-api")
o.Properties.Set("rpc.method", opID)
o.Properties.Set("rpc.service", ServiceID)
})
endTimer := startMetricTimer(ctx, "client.call.duration")
defer endTimer()
defer span.End()
handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) {
o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts")
})
decorated := middleware.DecorateHandler(handler, stack)
result, metadata, err = decorated.Handle(ctx, params)
if err != nil {
span.SetProperty("exception.type", fmt.Sprintf("%T", err))
span.SetProperty("exception.message", err.Error())
var aerr smithy.APIError
if errors.As(err, &aerr) {
span.SetProperty("api.error_code", aerr.ErrorCode())
span.SetProperty("api.error_message", aerr.ErrorMessage())
span.SetProperty("api.error_fault", aerr.ErrorFault().String())
}
err = &smithy.OperationError{
ServiceID: ServiceID,
OperationName: opID,
Err: err,
}
}
span.SetProperty("error", err != nil)
if err == nil {
span.SetStatus(tracing.SpanStatusOK)
} else {
span.SetStatus(tracing.SpanStatusError)
}
return result, metadata, err
}
@ -163,7 +345,7 @@ func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, o
if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil {
return fmt.Errorf("add ResolveEndpointV2: %v", err)
}
if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil {
if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil {
return fmt.Errorf("add Signing: %w", err)
}
return nil
@ -241,16 +423,15 @@ func setResolvedDefaultsMode(o *Options) {
// NewFromConfig returns a new client from the provided config.
func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client {
opts := Options{
Region: cfg.Region,
DefaultsMode: cfg.DefaultsMode,
RuntimeEnvironment: cfg.RuntimeEnvironment,
HTTPClient: cfg.HTTPClient,
Credentials: cfg.Credentials,
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
AccountIDEndpointMode: cfg.AccountIDEndpointMode,
Region: cfg.Region,
DefaultsMode: cfg.DefaultsMode,
RuntimeEnvironment: cfg.RuntimeEnvironment,
HTTPClient: cfg.HTTPClient,
Credentials: cfg.Credentials,
APIOptions: cfg.APIOptions,
Logger: cfg.Logger,
ClientLogMode: cfg.ClientLogMode,
AppID: cfg.AppID,
}
resolveAWSRetryerProvider(cfg, &opts)
resolveAWSRetryMaxAttempts(cfg, &opts)
@ -438,6 +619,30 @@ func addRawResponseToMetadata(stack *middleware.Stack) error {
func addRecordResponseTiming(stack *middleware.Stack) error {
return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After)
}
func addSpanRetryLoop(stack *middleware.Stack, options Options) error {
return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before)
}
type spanRetryLoop struct {
options Options
}
func (*spanRetryLoop) ID() string {
return "spanRetryLoop"
}
func (m *spanRetryLoop) HandleFinalize(
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
) (
middleware.FinalizeOutput, middleware.Metadata, error,
) {
tracer := operationTracer(m.options.TracerProvider)
ctx, span := tracer.StartSpan(ctx, "RetryLoop")
defer span.End()
return next.HandleFinalize(ctx, in)
}
func addStreamingEventsPayload(stack *middleware.Stack) error {
return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before)
}
@ -481,6 +686,7 @@ func addIsPaginatorUserAgent(o *Options) {
func addRetry(stack *middleware.Stack, o Options) error {
attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) {
m.LogAttempts = o.ClientLogMode.IsRetries()
m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts")
})
if err := stack.Finalize.Insert(attempt, "Signing", middleware.Before); err != nil {
return err
@ -544,25 +750,6 @@ func initializeTimeOffsetResolver(c *Client) {
c.timeOffset = new(atomic.Int64)
}
func checkAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) error {
switch mode {
case aws.AccountIDEndpointModeUnset:
case aws.AccountIDEndpointModePreferred:
case aws.AccountIDEndpointModeDisabled:
case aws.AccountIDEndpointModeRequired:
if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); !ok {
return fmt.Errorf("accountID is required but not set")
} else if ca.Credentials.AccountID == "" {
return fmt.Errorf("accountID is required but not set")
}
// default check in case invalid mode is configured through request config
default:
return fmt.Errorf("invalid accountID endpoint mode %s, must be preferred/required/disabled", mode)
}
return nil
}
func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
ua, err := getOrAddRequestUserAgent(stack)
if err != nil {
@ -578,6 +765,18 @@ func addUserAgentRetryMode(stack *middleware.Stack, options Options) error {
return nil
}
func resolveTracerProvider(options *Options) {
if options.TracerProvider == nil {
options.TracerProvider = &tracing.NopTracerProvider{}
}
}
func resolveMeterProvider(options *Options) {
if options.MeterProvider == nil {
options.MeterProvider = metrics.NopMeterProvider{}
}
}
func addRecursionDetection(stack *middleware.Stack) error {
return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After)
}
@ -777,3 +976,89 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error {
DisableHTTPS: o.EndpointOptions.DisableHTTPS,
}, "ResolveEndpointV2", middleware.After)
}
type spanInitializeStart struct {
}
func (*spanInitializeStart) ID() string {
return "spanInitializeStart"
}
func (m *spanInitializeStart) HandleInitialize(
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (
middleware.InitializeOutput, middleware.Metadata, error,
) {
ctx, _ = tracing.StartSpan(ctx, "Initialize")
return next.HandleInitialize(ctx, in)
}
type spanInitializeEnd struct {
}
func (*spanInitializeEnd) ID() string {
return "spanInitializeEnd"
}
func (m *spanInitializeEnd) HandleInitialize(
ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (
middleware.InitializeOutput, middleware.Metadata, error,
) {
ctx, span := tracing.PopSpan(ctx)
span.End()
return next.HandleInitialize(ctx, in)
}
type spanBuildRequestStart struct {
}
func (*spanBuildRequestStart) ID() string {
return "spanBuildRequestStart"
}
func (m *spanBuildRequestStart) HandleSerialize(
ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler,
) (
middleware.SerializeOutput, middleware.Metadata, error,
) {
ctx, _ = tracing.StartSpan(ctx, "BuildRequest")
return next.HandleSerialize(ctx, in)
}
type spanBuildRequestEnd struct {
}
func (*spanBuildRequestEnd) ID() string {
return "spanBuildRequestEnd"
}
func (m *spanBuildRequestEnd) HandleBuild(
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler,
) (
middleware.BuildOutput, middleware.Metadata, error,
) {
ctx, span := tracing.PopSpan(ctx)
span.End()
return next.HandleBuild(ctx, in)
}
func addSpanInitializeStart(stack *middleware.Stack) error {
return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before)
}
func addSpanInitializeEnd(stack *middleware.Stack) error {
return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After)
}
func addSpanBuildRequestStart(stack *middleware.Stack) error {
return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before)
}
func addSpanBuildRequestEnd(stack *middleware.Stack) error {
return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After)
}

View file

@ -16,7 +16,7 @@ import (
// Amazon Web Services resources. These temporary credentials consist of an access
// key ID, a secret access key, and a security token. Typically, you use AssumeRole
// within your account or for cross-account access. For a comparison of AssumeRole
// with other API operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Comparing the Amazon Web Services STS API operations] in the
// with other API operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the
// IAM User Guide.
//
// # Permissions
@ -26,16 +26,16 @@ import (
// cannot call the Amazon Web Services STS GetFederationToken or GetSessionToken
// API operations.
//
// (Optional) You can pass inline or managed [session policies] to this operation. You can pass a
// single JSON policy document to use as an inline session policy. You can also
// specify up to 10 managed policy Amazon Resource Names (ARNs) to use as managed
// session policies. The plaintext that you use for both inline and managed session
// policies can't exceed 2,048 characters. Passing policies to this operation
// returns new temporary credentials. The resulting session's permissions are the
// intersection of the role's identity-based policy and the session policies. You
// can use the role's temporary credentials in subsequent Amazon Web Services API
// calls to access resources in the account that owns the role. You cannot use
// session policies to grant more permissions than those allowed by the
// (Optional) You can pass inline or managed session policies to this operation.
// You can pass a single JSON policy document to use as an inline session policy.
// You can also specify up to 10 managed policy Amazon Resource Names (ARNs) to use
// as managed session policies. The plaintext that you use for both inline and
// managed session policies can't exceed 2,048 characters. Passing policies to this
// operation returns new temporary credentials. The resulting session's permissions
// are the intersection of the role's identity-based policy and the session
// policies. You can use the role's temporary credentials in subsequent Amazon Web
// Services API calls to access resources in the account that owns the role. You
// cannot use session policies to grant more permissions than those allowed by the
// identity-based policy of the role that is being assumed. For more information,
// see [Session Policies]in the IAM User Guide.
//
@ -104,10 +104,9 @@ import (
// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html
// [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining
// [Comparing the Amazon Web Services STS API operations]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison
// [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [IAM Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html
func (c *Client) AssumeRole(ctx context.Context, params *AssumeRoleInput, optFns ...func(*Options)) (*AssumeRoleOutput, error) {
if params == nil {
@ -141,10 +140,18 @@ type AssumeRoleInput struct {
// the temporary security credentials will expose the role session name to the
// external account in their CloudTrail logs.
//
// For security purposes, administrators can view this field in [CloudTrail logs] to help identify
// who performed an action in Amazon Web Services. Your administrator might require
// that you specify your user name as the session name when you assume the role.
// For more information, see [sts:RoleSessionName]sts:RoleSessionName .
//
// The regex used to validate this parameter is a string of characters consisting
// of upper- and lower-case alphanumeric characters with no spaces. You can also
// include underscores or any of the following characters: =,.@-
//
// [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds
// [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname
//
// This member is required.
RoleSessionName *string
@ -163,7 +170,7 @@ type AssumeRoleInput struct {
// 43200 seconds (12 hours), depending on the maximum session duration setting for
// your role. However, if you assume a role using role chaining and provide a
// DurationSeconds parameter value greater than one hour, the operation fails. To
// learn how to view the maximum value for your role, see [View the Maximum Session Duration Setting for a Role]in the IAM User Guide.
// learn how to view the maximum value for your role, see [Update the maximum session duration for a role].
//
// By default, the value is set to 3600 seconds.
//
@ -173,7 +180,7 @@ type AssumeRoleInput struct {
// parameter that specifies the maximum length of the console session. For more
// information, see [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]in the IAM User Guide.
//
// [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session
// [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration
// [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html
DurationSeconds *int32
@ -218,7 +225,10 @@ type AssumeRoleInput struct {
// by percentage how close the policies and tags for your request are to the upper
// size limit.
//
// For more information about role session permissions, see [Session policies].
//
// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
Policy *string
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want to
@ -273,10 +283,10 @@ type AssumeRoleInput struct {
SerialNumber *string
// The source identity specified by the principal that is calling the AssumeRole
// operation.
// operation. The source identity value persists across [chained role]sessions.
//
// You can require users to specify a source identity when they assume a role. You
// do this by using the sts:SourceIdentity condition key in a role trust policy.
// do this by using the [sts:SourceIdentity]sts:SourceIdentity condition key in a role trust policy.
// You can use source identity information in CloudTrail logs to determine who took
// actions with a role. You can use the aws:SourceIdentity condition key to
// further control access to Amazon Web Services resources based on the value of
@ -289,7 +299,9 @@ type AssumeRoleInput struct {
// value that begins with the text aws: . This prefix is reserved for Amazon Web
// Services internal use.
//
// [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-role-chaining
// [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
// [sts:SourceIdentity]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceidentity
SourceIdentity *string
// A list of session tags that you want to pass. Each session tag consists of a
@ -342,8 +354,8 @@ type AssumeRoleInput struct {
// a tag key as transitive, the corresponding key and value passes to subsequent
// sessions in a role chain. For more information, see [Chaining Roles with Session Tags]in the IAM User Guide.
//
// This parameter is optional. When you set session tags as transitive, the
// session policy and session tags packed binary limit is not affected.
// This parameter is optional. The transitive status of a session tag does not
// impact its packed binary size.
//
// If you choose not to specify a transitive tag key, then no tags are passed from
// this session to any subsequent sessions.
@ -445,6 +457,9 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -484,6 +499,18 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -16,7 +16,7 @@ import (
// mechanism for tying an enterprise identity store or directory to role-based
// Amazon Web Services access without user-specific credentials or configuration.
// For a comparison of AssumeRoleWithSAML with the other API operations that
// produce temporary credentials, see [Requesting Temporary Security Credentials]and [Comparing the Amazon Web Services STS API operations] in the IAM User Guide.
// produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide.
//
// The temporary security credentials returned by this operation consist of an
// access key ID, a secret access key, and a security token. Applications can use
@ -130,10 +130,10 @@ import (
// [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session
// [Creating a Role for SAML 2.0 Federation]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html
// [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length
// [Comparing the Amazon Web Services STS API operations]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison
// [Creating SAML Identity Providers]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html
// [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html
// [Configuring a Relying Party and Claims]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html
// [Role chaining]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining
@ -219,6 +219,8 @@ type AssumeRoleWithSAMLInput struct {
// \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage
// return (\u000D) characters.
//
// For more information about role session permissions, see [Session policies].
//
// An Amazon Web Services conversion compresses the passed inline session policy,
// managed policy ARNs, and session tags into a packed binary format that has a
// separate limit. Your request can fail for this limit even if your plaintext
@ -227,6 +229,7 @@ type AssumeRoleWithSAMLInput struct {
// size limit.
//
// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
Policy *string
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want to
@ -304,7 +307,8 @@ type AssumeRoleWithSAMLOutput struct {
// allowed space.
PackedPolicySize *int32
// The value in the SourceIdentity attribute in the SAML assertion.
// The value in the SourceIdentity attribute in the SAML assertion. The source
// identity value persists across [chained role]sessions.
//
// You can require users to set a source identity value when they assume a role.
// You do this by using the sts:SourceIdentity condition key in a role trust
@ -321,7 +325,7 @@ type AssumeRoleWithSAMLOutput struct {
// of upper- and lower-case alphanumeric characters with no spaces. You can also
// include underscores or any of the following characters: =,.@-
//
// [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts#iam-term-role-chaining
// [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#id_roles_terms-and-concepts
// [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
SourceIdentity *string
@ -385,6 +389,9 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -424,6 +431,18 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -31,7 +31,7 @@ import (
// Services credentials. Instead, the identity of the caller is validated by using
// a token from the web identity provider. For a comparison of
// AssumeRoleWithWebIdentity with the other API operations that produce temporary
// credentials, see [Requesting Temporary Security Credentials]and [Comparing the Amazon Web Services STS API operations] in the IAM User Guide.
// credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide.
//
// The temporary security credentials returned by this API consist of an access
// key ID, a secret access key, and a security token. Applications can use these
@ -45,7 +45,7 @@ import (
// DurationSeconds parameter to specify the duration of your session. You can
// provide a value from 900 seconds (15 minutes) up to the maximum session duration
// setting for the role. This setting can have a value from 1 hour to 12 hours. To
// learn how to view the maximum value for your role, see [View the Maximum Session Duration Setting for a Role]in the IAM User Guide.
// learn how to view the maximum value for your role, see [Update the maximum session duration for a role]in the IAM User Guide.
// The maximum session duration limit applies when you use the AssumeRole* API
// operations or the assume-role* CLI commands. However the limit does not apply
// when you use those operations to create a console URL. For more information, see
@ -111,34 +111,23 @@ import (
// that you avoid using any personally identifiable information (PII) in this
// field. For example, you could instead use a GUID or a pairwise identifier, as [suggested in the OIDC specification].
//
// For more information about how to use web identity federation and the
// For more information about how to use OIDC federation and the
// AssumeRoleWithWebIdentity API, see the following resources:
//
// [Using Web Identity Federation API Operations for Mobile Apps]
// - and [Federation Through a Web-based Identity Provider].
//
// [Web Identity Federation Playground]
// - . Walk through the process of authenticating through Login with Amazon,
// Facebook, or Google, getting temporary security credentials, and then using
// those credentials to make a request to Amazon Web Services.
//
// [Amazon Web Services SDK for iOS Developer Guide]
// - and [Amazon Web Services SDK for Android Developer Guide]. These toolkits contain sample apps that show how to invoke the
// identity providers. The toolkits then show how to use the information from these
// providers to get and use temporary security credentials.
//
// [Web Identity Federation with Mobile Applications]
// - . This article discusses web identity federation and shows an example of
// how to use web identity federation to get access to content in Amazon S3.
//
// [Amazon Web Services SDK for iOS Developer Guide]: http://aws.amazon.com/sdkforios/
// [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session
// [Web Identity Federation Playground]: https://aws.amazon.com/blogs/aws/the-aws-web-identity-federation-playground/
// [Amazon Web Services SDK for Android Developer Guide]: http://aws.amazon.com/sdkforandroid/
// [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length
// [Comparing the Amazon Web Services STS API operations]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison
// [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
// [Subject]: http://openid.net/specs/openid-connect-core-1_0.html#Claims
// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html
// [Amazon Cognito identity pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
@ -148,7 +137,7 @@ import (
// [Amazon Cognito federated identities]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html
// [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining
// [Web Identity Federation with Mobile Applications]: http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications
// [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration
// [Using Web Identity Federation API Operations for Mobile Apps]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html
// [suggested in the OIDC specification]: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
func (c *Client) AssumeRoleWithWebIdentity(ctx context.Context, params *AssumeRoleWithWebIdentityInput, optFns ...func(*Options)) (*AssumeRoleWithWebIdentityOutput, error) {
@ -170,6 +159,17 @@ type AssumeRoleWithWebIdentityInput struct {
// The Amazon Resource Name (ARN) of the role that the caller is assuming.
//
// Additional considerations apply to Amazon Cognito identity pools that assume [cross-account IAM roles].
// The trust policies of these roles must accept the cognito-identity.amazonaws.com
// service principal and must contain the cognito-identity.amazonaws.com:aud
// condition key to restrict role assumption to users from your intended identity
// pools. A policy that trusts Amazon Cognito identity pools without this condition
// creates a risk that a user from an unintended identity pool can assume the role.
// For more information, see [Trust policies for IAM roles in Basic (Classic) authentication]in the Amazon Cognito Developer Guide.
//
// [cross-account IAM roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html
// [Trust policies for IAM roles in Basic (Classic) authentication]: https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#trust-policies
//
// This member is required.
RoleArn *string
@ -179,17 +179,26 @@ type AssumeRoleWithWebIdentityInput struct {
// associated with that user. This session name is included as part of the ARN and
// assumed role ID in the AssumedRoleUser response element.
//
// For security purposes, administrators can view this field in [CloudTrail logs] to help identify
// who performed an action in Amazon Web Services. Your administrator might require
// that you specify your user name as the session name when you assume the role.
// For more information, see [sts:RoleSessionName]sts:RoleSessionName .
//
// The regex used to validate this parameter is a string of characters consisting
// of upper- and lower-case alphanumeric characters with no spaces. You can also
// include underscores or any of the following characters: =,.@-
//
// [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds
// [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname
//
// This member is required.
RoleSessionName *string
// The OAuth 2.0 access token or OpenID Connect ID token that is provided by the
// identity provider. Your application must get this token by authenticating the
// user who is using your application with a web identity provider before the
// application makes an AssumeRoleWithWebIdentity call. Only tokens with RSA
// application makes an AssumeRoleWithWebIdentity call. Timestamps in the token
// must be formatted as either an integer or a long integer. Only tokens with RSA
// algorithms (RS256) are supported.
//
// This member is required.
@ -232,6 +241,8 @@ type AssumeRoleWithWebIdentityInput struct {
// \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage
// return (\u000D) characters.
//
// For more information about role session permissions, see [Session policies].
//
// An Amazon Web Services conversion compresses the passed inline session policy,
// managed policy ARNs, and session tags into a packed binary format that has a
// separate limit. Your request can fail for this limit even if your plaintext
@ -240,6 +251,7 @@ type AssumeRoleWithWebIdentityInput struct {
// size limit.
//
// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
Policy *string
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want to
@ -337,7 +349,7 @@ type AssumeRoleWithWebIdentityOutput struct {
// of upper- and lower-case alphanumeric characters with no spaces. You can also
// include underscores or any of the following characters: =,.@-
//
// [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts#iam-term-role-chaining
// [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#id_roles_terms-and-concepts
// [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
// [Using Tokens with User Pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
SourceIdentity *string
@ -396,6 +408,9 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -435,6 +450,18 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -0,0 +1,221 @@
// Code generated by smithy-go-codegen DO NOT EDIT.
package sts
import (
"context"
"fmt"
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
"github.com/aws/aws-sdk-go-v2/service/sts/types"
"github.com/aws/smithy-go/middleware"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
// Returns a set of short term credentials you can use to perform privileged tasks
// in a member account.
//
// Before you can launch a privileged session, you must have enabled centralized
// root access in your organization. For steps to enable this feature, see [Centralize root access for member accounts]in the
// IAM User Guide.
//
// The global endpoint is not supported for AssumeRoot. You must send this request
// to a Regional STS endpoint. For more information, see [Endpoints].
//
// You can track AssumeRoot in CloudTrail logs to determine what actions were
// performed in a session. For more information, see [Track privileged tasks in CloudTrail]in the IAM User Guide.
//
// [Endpoints]: https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html#sts-endpoints
// [Track privileged tasks in CloudTrail]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-track-privileged-tasks.html
// [Centralize root access for member accounts]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-enable-root-access.html
func (c *Client) AssumeRoot(ctx context.Context, params *AssumeRootInput, optFns ...func(*Options)) (*AssumeRootOutput, error) {
if params == nil {
params = &AssumeRootInput{}
}
result, metadata, err := c.invokeOperation(ctx, "AssumeRoot", params, optFns, c.addOperationAssumeRootMiddlewares)
if err != nil {
return nil, err
}
out := result.(*AssumeRootOutput)
out.ResultMetadata = metadata
return out, nil
}
type AssumeRootInput struct {
// The member account principal ARN or account ID.
//
// This member is required.
TargetPrincipal *string
// The identity based policy that scopes the session to the privileged tasks that
// can be performed. You can use one of following Amazon Web Services managed
// policies to scope root session actions. You can add additional customer managed
// policies to further limit the permissions for the root session.
//
// [IAMAuditRootUserCredentials]
//
// [IAMCreateRootUserPassword]
//
// [IAMDeleteRootUserCredentials]
//
// [S3UnlockBucketPolicy]
//
// [SQSUnlockQueuePolicy]
//
// [IAMDeleteRootUserCredentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-IAMDeleteRootUserCredentials
// [IAMCreateRootUserPassword]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-IAMCreateRootUserPassword
// [IAMAuditRootUserCredentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-IAMAuditRootUserCredentials
// [S3UnlockBucketPolicy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-S3UnlockBucketPolicy
// [SQSUnlockQueuePolicy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-SQSUnlockQueuePolicy
//
// This member is required.
TaskPolicyArn *types.PolicyDescriptorType
// The duration, in seconds, of the privileged session. The value can range from 0
// seconds up to the maximum session duration of 900 seconds (15 minutes). If you
// specify a value higher than this setting, the operation fails.
//
// By default, the value is set to 900 seconds.
DurationSeconds *int32
noSmithyDocumentSerde
}
type AssumeRootOutput struct {
// The temporary security credentials, which include an access key ID, a secret
// access key, and a security token.
//
// The size of the security token that STS API operations return is not fixed. We
// strongly recommend that you make no assumptions about the maximum size.
Credentials *types.Credentials
// The source identity specified by the principal that is calling the AssumeRoot
// operation.
//
// You can use the aws:SourceIdentity condition key to control access based on the
// value of source identity. For more information about using source identity, see [Monitor and control actions taken with assumed roles]
// in the IAM User Guide.
//
// The regex used to validate this parameter is a string of characters consisting
// of upper- and lower-case alphanumeric characters with no spaces. You can also
// include underscores or any of the following characters: =,.@-
//
// [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
SourceIdentity *string
// Metadata pertaining to the operation's result.
ResultMetadata middleware.Metadata
noSmithyDocumentSerde
}
func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, options Options) (err error) {
if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
return err
}
err = stack.Serialize.Add(&awsAwsquery_serializeOpAssumeRoot{}, middleware.After)
if err != nil {
return err
}
err = stack.Deserialize.Add(&awsAwsquery_deserializeOpAssumeRoot{}, middleware.After)
if err != nil {
return err
}
if err := addProtocolFinalizerMiddlewares(stack, options, "AssumeRoot"); err != nil {
return fmt.Errorf("add protocol finalizers: %v", err)
}
if err = addlegacyEndpointContextSetter(stack, options); err != nil {
return err
}
if err = addSetLoggerMiddleware(stack, options); err != nil {
return err
}
if err = addClientRequestID(stack); err != nil {
return err
}
if err = addComputeContentLength(stack); err != nil {
return err
}
if err = addResolveEndpointMiddleware(stack, options); err != nil {
return err
}
if err = addComputePayloadSHA256(stack); err != nil {
return err
}
if err = addRetry(stack, options); err != nil {
return err
}
if err = addRawResponseToMetadata(stack); err != nil {
return err
}
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
return err
}
if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
return err
}
if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
return err
}
if err = addTimeOffsetBuild(stack, c); err != nil {
return err
}
if err = addUserAgentRetryMode(stack, options); err != nil {
return err
}
if err = addOpAssumeRootValidationMiddleware(stack); err != nil {
return err
}
if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssumeRoot(options.Region), middleware.Before); err != nil {
return err
}
if err = addRecursionDetection(stack); err != nil {
return err
}
if err = addRequestIDRetrieverMiddleware(stack); err != nil {
return err
}
if err = addResponseErrorMiddleware(stack); err != nil {
return err
}
if err = addRequestResponseLogging(stack, options); err != nil {
return err
}
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}
func newServiceMetadataMiddleware_opAssumeRoot(region string) *awsmiddleware.RegisterServiceMetadata {
return &awsmiddleware.RegisterServiceMetadata{
Region: region,
ServiceID: ServiceID,
OperationName: "AssumeRoot",
}
}

View file

@ -126,6 +126,9 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -165,6 +168,18 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -117,6 +117,9 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -156,6 +159,18 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -108,6 +108,9 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -144,6 +147,18 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -20,7 +20,7 @@ import (
// credentials of an IAM user. As a result, this call is appropriate in contexts
// where those credentials can be safeguarded, usually in a server-based
// application. For a comparison of GetFederationToken with the other API
// operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Comparing the Amazon Web Services STS API operations] in the IAM User Guide.
// operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide.
//
// Although it is possible to call GetFederationToken using the security
// credentials of an Amazon Web Services account root user rather than an IAM user
@ -104,9 +104,9 @@ import (
// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html
// [GetFederationToken—Federation Through a Custom Identity Broker]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken
// [Comparing the Amazon Web Services STS API operations]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison
// [Safeguard your root user credentials and don't use them for everyday tasks]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#lock-away-credentials
// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html
func (c *Client) GetFederationToken(ctx context.Context, params *GetFederationTokenInput, optFns ...func(*Options)) (*GetFederationTokenOutput, error) {
if params == nil {
@ -330,6 +330,9 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -369,6 +372,18 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -22,7 +22,7 @@ import (
// the call returns, IAM users can then make programmatic calls to API operations
// that require MFA authentication. An incorrect MFA code causes the API to return
// an access denied error. For a comparison of GetSessionToken with the other API
// operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Comparing the Amazon Web Services STS API operations] in the IAM User Guide.
// operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide.
//
// No permissions are required for users to perform this operation. The purpose of
// the sts:GetSessionToken operation is to authenticate the user using MFA. You
@ -63,10 +63,10 @@ import (
// credentials, see [Temporary Credentials for Users in Untrusted Environments]in the IAM User Guide.
//
// [Permissions for GetSessionToken]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getsessiontoken.html
// [Comparing the Amazon Web Services STS API operations]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison
// [Temporary Credentials for Users in Untrusted Environments]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken
// [Safeguard your root user credentials and don't use them for everyday tasks]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#lock-away-credentials
// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
func (c *Client) GetSessionToken(ctx context.Context, params *GetSessionTokenInput, optFns ...func(*Options)) (*GetSessionTokenOutput, error) {
if params == nil {
params = &GetSessionTokenInput{}
@ -179,6 +179,9 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack,
if err = addRecordResponseTiming(stack); err != nil {
return err
}
if err = addSpanRetryLoop(stack, options); err != nil {
return err
}
if err = addClientUserAgent(stack, options); err != nil {
return err
}
@ -215,6 +218,18 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack,
if err = addDisableHTTPSMiddleware(stack, options); err != nil {
return err
}
if err = addSpanInitializeStart(stack); err != nil {
return err
}
if err = addSpanInitializeEnd(stack); err != nil {
return err
}
if err = addSpanBuildRequestStart(stack); err != nil {
return err
}
if err = addSpanBuildRequestEnd(stack); err != nil {
return err
}
return nil
}

View file

@ -8,7 +8,9 @@ import (
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
smithy "github.com/aws/smithy-go"
smithyauth "github.com/aws/smithy-go/auth"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
)
@ -157,6 +159,9 @@ func (*resolveAuthSchemeMiddleware) ID() string {
func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "ResolveAuthScheme")
defer span.End()
params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options)
options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params)
if err != nil {
@ -169,6 +174,9 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid
}
ctx = setResolvedAuthScheme(ctx, scheme)
span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID())
span.End()
return next.HandleFinalize(ctx, in)
}
@ -228,7 +236,10 @@ func (*getIdentityMiddleware) ID() string {
func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
rscheme := getResolvedAuthScheme(ctx)
innerCtx, span := tracing.StartSpan(ctx, "GetIdentity")
defer span.End()
rscheme := getResolvedAuthScheme(innerCtx)
if rscheme == nil {
return out, metadata, fmt.Errorf("no resolved auth scheme")
}
@ -238,12 +249,20 @@ func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middlewar
return out, metadata, fmt.Errorf("no identity resolver")
}
identity, err := resolver.GetIdentity(ctx, rscheme.IdentityProperties)
identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration",
func() (smithyauth.Identity, error) {
return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties)
},
func(o *metrics.RecordMetricOptions) {
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
})
if err != nil {
return out, metadata, fmt.Errorf("get identity: %w", err)
}
ctx = setIdentity(ctx, identity)
span.End()
return next.HandleFinalize(ctx, in)
}
@ -259,6 +278,7 @@ func getIdentity(ctx context.Context) smithyauth.Identity {
}
type signRequestMiddleware struct {
options Options
}
func (*signRequestMiddleware) ID() string {
@ -268,6 +288,9 @@ func (*signRequestMiddleware) ID() string {
func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "SignRequest")
defer span.End()
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request)
@ -288,9 +311,15 @@ func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middlewar
return out, metadata, fmt.Errorf("no signer")
}
if err := signer.SignRequest(ctx, req, identity, rscheme.SignerProperties); err != nil {
_, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) {
return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties)
}, func(o *metrics.RecordMetricOptions) {
o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID())
})
if err != nil {
return out, metadata, fmt.Errorf("sign request: %w", err)
}
span.End()
return next.HandleFinalize(ctx, in)
}

View file

@ -16,6 +16,7 @@ import (
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/ptr"
smithytime "github.com/aws/smithy-go/time"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"io"
"strconv"
@ -46,6 +47,10 @@ func (m *awsAwsquery_deserializeOpAssumeRole) HandleDeserialize(ctx context.Cont
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -163,6 +168,10 @@ func (m *awsAwsquery_deserializeOpAssumeRoleWithSAML) HandleDeserialize(ctx cont
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -286,6 +295,10 @@ func (m *awsAwsquery_deserializeOpAssumeRoleWithWebIdentity) HandleDeserialize(c
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -397,6 +410,121 @@ func awsAwsquery_deserializeOpErrorAssumeRoleWithWebIdentity(response *smithyhtt
}
}
type awsAwsquery_deserializeOpAssumeRoot struct {
}
func (*awsAwsquery_deserializeOpAssumeRoot) ID() string {
return "OperationDeserializer"
}
func (m *awsAwsquery_deserializeOpAssumeRoot) 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)
if err != nil {
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
}
if response.StatusCode < 200 || response.StatusCode >= 300 {
return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoot(response, &metadata)
}
output := &AssumeRootOutput{}
out.Result = output
var buff [1024]byte
ringBuffer := smithyio.NewRingBuffer(buff[:])
body := io.TeeReader(response.Body, ringBuffer)
rootDecoder := xml.NewDecoder(body)
t, err := smithyxml.FetchRootElement(rootDecoder)
if err == io.EOF {
return out, metadata, nil
}
if err != nil {
var snapshot bytes.Buffer
io.Copy(&snapshot, ringBuffer)
return out, metadata, &smithy.DeserializationError{
Err: fmt.Errorf("failed to decode response body, %w", err),
Snapshot: snapshot.Bytes(),
}
}
decoder := smithyxml.WrapNodeDecoder(rootDecoder, t)
t, err = decoder.GetElement("AssumeRootResult")
if err != nil {
var snapshot bytes.Buffer
io.Copy(&snapshot, ringBuffer)
err = &smithy.DeserializationError{
Err: fmt.Errorf("failed to decode response body, %w", err),
Snapshot: snapshot.Bytes(),
}
return out, metadata, err
}
decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t)
err = awsAwsquery_deserializeOpDocumentAssumeRootOutput(&output, decoder)
if err != nil {
var snapshot bytes.Buffer
io.Copy(&snapshot, ringBuffer)
err = &smithy.DeserializationError{
Err: fmt.Errorf("failed to decode response body, %w", err),
Snapshot: snapshot.Bytes(),
}
return out, metadata, err
}
return out, metadata, err
}
func awsAwsquery_deserializeOpErrorAssumeRoot(response *smithyhttp.Response, metadata *middleware.Metadata) error {
var errorBuffer bytes.Buffer
if _, err := io.Copy(&errorBuffer, response.Body); err != nil {
return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)}
}
errorBody := bytes.NewReader(errorBuffer.Bytes())
errorCode := "UnknownError"
errorMessage := errorCode
errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false)
if err != nil {
return err
}
if reqID := errorComponents.RequestID; len(reqID) != 0 {
awsmiddleware.SetRequestIDMetadata(metadata, reqID)
}
if len(errorComponents.Code) != 0 {
errorCode = errorComponents.Code
}
if len(errorComponents.Message) != 0 {
errorMessage = errorComponents.Message
}
errorBody.Seek(0, io.SeekStart)
switch {
case strings.EqualFold("ExpiredTokenException", errorCode):
return awsAwsquery_deserializeErrorExpiredTokenException(response, errorBody)
case strings.EqualFold("RegionDisabledException", errorCode):
return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody)
default:
genericError := &smithy.GenericAPIError{
Code: errorCode,
Message: errorMessage,
}
return genericError
}
}
type awsAwsquery_deserializeOpDecodeAuthorizationMessage struct {
}
@ -412,6 +540,10 @@ func (m *awsAwsquery_deserializeOpDecodeAuthorizationMessage) HandleDeserialize(
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -520,6 +652,10 @@ func (m *awsAwsquery_deserializeOpGetAccessKeyInfo) HandleDeserialize(ctx contex
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -625,6 +761,10 @@ func (m *awsAwsquery_deserializeOpGetCallerIdentity) HandleDeserialize(ctx conte
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -730,6 +870,10 @@ func (m *awsAwsquery_deserializeOpGetFederationToken) HandleDeserialize(ctx cont
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -844,6 +988,10 @@ func (m *awsAwsquery_deserializeOpGetSessionToken) HandleDeserialize(ctx context
return out, metadata, err
}
_, span := tracing.StartSpan(ctx, "OperationDeserializer")
endTimer := startMetricTimer(ctx, "client.call.deserialization_duration")
defer endTimer()
defer span.End()
response, ok := out.RawResponse.(*smithyhttp.Response)
if !ok {
return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
@ -2235,6 +2383,61 @@ func awsAwsquery_deserializeOpDocumentAssumeRoleWithWebIdentityOutput(v **Assume
return nil
}
func awsAwsquery_deserializeOpDocumentAssumeRootOutput(v **AssumeRootOutput, decoder smithyxml.NodeDecoder) error {
if v == nil {
return fmt.Errorf("unexpected nil of type %T", v)
}
var sv *AssumeRootOutput
if *v == nil {
sv = &AssumeRootOutput{}
} else {
sv = *v
}
for {
t, done, err := decoder.Token()
if err != nil {
return err
}
if done {
break
}
originalDecoder := decoder
decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t)
switch {
case strings.EqualFold("Credentials", t.Name.Local):
nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t)
if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil {
return err
}
case strings.EqualFold("SourceIdentity", t.Name.Local):
val, err := decoder.Value()
if err != nil {
return err
}
if val == nil {
break
}
{
xtv := string(val)
sv.SourceIdentity = ptr.String(xtv)
}
default:
// Do nothing and ignore the unexpected tag element
err = decoder.Decoder.Skip()
if err != nil {
return err
}
}
decoder = originalDecoder
}
*v = sv
return nil
}
func awsAwsquery_deserializeOpDocumentDecodeAuthorizationMessageOutput(v **DecodeAuthorizationMessageOutput, decoder smithyxml.NodeDecoder) error {
if v == nil {
return fmt.Errorf("unexpected nil of type %T", v)

View file

@ -17,6 +17,7 @@ import (
smithyendpoints "github.com/aws/smithy-go/endpoints"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/ptr"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net/http"
"net/url"
@ -1082,14 +1083,13 @@ func (*resolveEndpointV2Middleware) ID() string {
func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "ResolveEndpoint")
defer span.End()
if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
return next.HandleFinalize(ctx, in)
}
if err := checkAccountID(getIdentity(ctx), m.options.AccountIDEndpointMode); err != nil {
return out, metadata, fmt.Errorf("invalid accountID set: %w", err)
}
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
@ -1100,11 +1100,16 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid
}
params := bindEndpointParams(ctx, getOperationInput(ctx), m.options)
endpt, err := m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration",
func() (smithyendpoints.Endpoint, error) {
return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
})
if err != nil {
return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
}
span.SetProperty("client.call.resolved_endpoint", endpt.URI.String())
if endpt.URI.RawPath == "" && req.URL.RawPath != "" {
endpt.URI.RawPath = endpt.URI.Path
}
@ -1126,5 +1131,6 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid
rscheme.SignerProperties.SetAll(&o.SignerProperties)
}
span.End()
return next.HandleFinalize(ctx, in)
}

View file

@ -13,6 +13,7 @@
"api_op_AssumeRole.go",
"api_op_AssumeRoleWithSAML.go",
"api_op_AssumeRoleWithWebIdentity.go",
"api_op_AssumeRoot.go",
"api_op_DecodeAuthorizationMessage.go",
"api_op_GetAccessKeyInfo.go",
"api_op_GetCallerIdentity.go",

View file

@ -3,4 +3,4 @@
package sts
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.30.5"
const goModuleVersion = "1.33.3"

View file

@ -94,7 +94,7 @@ var partitionRegexp = struct {
AwsUsGov *regexp.Regexp
}{
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"),
Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"),
AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"),
AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"),
AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"),

View file

@ -9,7 +9,9 @@ import (
internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy"
smithyauth "github.com/aws/smithy-go/auth"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"net/http"
)
@ -24,9 +26,6 @@ type Options struct {
// modify this list for per operation behavior.
APIOptions []func(*middleware.Stack) error
// Indicates how aws account ID is applied in endpoint2.0 routing
AccountIDEndpointMode aws.AccountIDEndpointMode
// The optional application specific identifier appended to the User-Agent header.
AppID string
@ -69,6 +68,9 @@ type Options struct {
// The logger writer interface to write logging messages to.
Logger logging.Logger
// The client meter provider.
MeterProvider metrics.MeterProvider
// The region to send requests to. (Required)
Region string
@ -103,6 +105,9 @@ type Options struct {
// within your applications.
RuntimeEnvironment aws.RuntimeEnvironment
// The client tracer provider.
TracerProvider tracing.TracerProvider
// The initial DefaultsMode used when the client options were constructed. If the
// DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved
// value was at that point in time.

View file

@ -11,6 +11,7 @@ import (
smithy "github.com/aws/smithy-go"
"github.com/aws/smithy-go/encoding/httpbinding"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
smithyhttp "github.com/aws/smithy-go/transport/http"
"path"
)
@ -25,6 +26,10 @@ func (*awsAwsquery_serializeOpAssumeRole) ID() string {
func (m *awsAwsquery_serializeOpAssumeRole) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -76,6 +81,8 @@ func (m *awsAwsquery_serializeOpAssumeRole) HandleSerialize(ctx context.Context,
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -89,6 +96,10 @@ func (*awsAwsquery_serializeOpAssumeRoleWithSAML) ID() string {
func (m *awsAwsquery_serializeOpAssumeRoleWithSAML) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -140,6 +151,8 @@ func (m *awsAwsquery_serializeOpAssumeRoleWithSAML) HandleSerialize(ctx context.
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -153,6 +166,10 @@ func (*awsAwsquery_serializeOpAssumeRoleWithWebIdentity) ID() string {
func (m *awsAwsquery_serializeOpAssumeRoleWithWebIdentity) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -204,6 +221,78 @@ func (m *awsAwsquery_serializeOpAssumeRoleWithWebIdentity) HandleSerialize(ctx c
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
type awsAwsquery_serializeOpAssumeRoot struct {
}
func (*awsAwsquery_serializeOpAssumeRoot) ID() string {
return "OperationSerializer"
}
func (m *awsAwsquery_serializeOpAssumeRoot) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
}
input, ok := in.Parameters.(*AssumeRootInput)
_ = input
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)}
}
operationPath := "/"
if len(request.Request.URL.Path) == 0 {
request.Request.URL.Path = operationPath
} else {
request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath)
if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' {
request.Request.URL.Path += "/"
}
}
request.Request.Method = "POST"
httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header)
if err != nil {
return out, metadata, &smithy.SerializationError{Err: err}
}
httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded")
bodyWriter := bytes.NewBuffer(nil)
bodyEncoder := query.NewEncoder(bodyWriter)
body := bodyEncoder.Object()
body.Key("Action").String("AssumeRoot")
body.Key("Version").String("2011-06-15")
if err := awsAwsquery_serializeOpDocumentAssumeRootInput(input, bodyEncoder.Value); err != nil {
return out, metadata, &smithy.SerializationError{Err: err}
}
err = bodyEncoder.Encode()
if err != nil {
return out, metadata, &smithy.SerializationError{Err: err}
}
if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil {
return out, metadata, &smithy.SerializationError{Err: err}
}
if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil {
return out, metadata, &smithy.SerializationError{Err: err}
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -217,6 +306,10 @@ func (*awsAwsquery_serializeOpDecodeAuthorizationMessage) ID() string {
func (m *awsAwsquery_serializeOpDecodeAuthorizationMessage) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -268,6 +361,8 @@ func (m *awsAwsquery_serializeOpDecodeAuthorizationMessage) HandleSerialize(ctx
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -281,6 +376,10 @@ func (*awsAwsquery_serializeOpGetAccessKeyInfo) ID() string {
func (m *awsAwsquery_serializeOpGetAccessKeyInfo) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -332,6 +431,8 @@ func (m *awsAwsquery_serializeOpGetAccessKeyInfo) HandleSerialize(ctx context.Co
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -345,6 +446,10 @@ func (*awsAwsquery_serializeOpGetCallerIdentity) ID() string {
func (m *awsAwsquery_serializeOpGetCallerIdentity) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -392,6 +497,8 @@ func (m *awsAwsquery_serializeOpGetCallerIdentity) HandleSerialize(ctx context.C
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -405,6 +512,10 @@ func (*awsAwsquery_serializeOpGetFederationToken) ID() string {
func (m *awsAwsquery_serializeOpGetFederationToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -456,6 +567,8 @@ func (m *awsAwsquery_serializeOpGetFederationToken) HandleSerialize(ctx context.
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
@ -469,6 +582,10 @@ func (*awsAwsquery_serializeOpGetSessionToken) ID() string {
func (m *awsAwsquery_serializeOpGetSessionToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
_, span := tracing.StartSpan(ctx, "OperationSerializer")
endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
defer endTimer()
defer span.End()
request, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)}
@ -520,6 +637,8 @@ func (m *awsAwsquery_serializeOpGetSessionToken) HandleSerialize(ctx context.Con
}
in.Request = request
endTimer()
span.End()
return next.HandleSerialize(ctx, in)
}
func awsAwsquery_serializeDocumentPolicyDescriptorListType(v []types.PolicyDescriptorType, value query.Value) error {
@ -772,6 +891,30 @@ func awsAwsquery_serializeOpDocumentAssumeRoleWithWebIdentityInput(v *AssumeRole
return nil
}
func awsAwsquery_serializeOpDocumentAssumeRootInput(v *AssumeRootInput, value query.Value) error {
object := value.Object()
_ = object
if v.DurationSeconds != nil {
objectKey := object.Key("DurationSeconds")
objectKey.Integer(*v.DurationSeconds)
}
if v.TargetPrincipal != nil {
objectKey := object.Key("TargetPrincipal")
objectKey.String(*v.TargetPrincipal)
}
if v.TaskPolicyArn != nil {
objectKey := object.Key("TaskPolicyArn")
if err := awsAwsquery_serializeDocumentPolicyDescriptorType(v.TaskPolicyArn, objectKey); err != nil {
return err
}
}
return nil
}
func awsAwsquery_serializeOpDocumentDecodeAuthorizationMessageInput(v *DecodeAuthorizationMessageInput, value query.Value) error {
object := value.Object()
_ = object

View file

@ -95,8 +95,8 @@ func (e *IDPRejectedClaimException) ErrorCode() string {
func (e *IDPRejectedClaimException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient }
// The error returned if the message passed to DecodeAuthorizationMessage was
// invalid. This can happen if the token contains invalid characters, such as
// linebreaks.
// invalid. This can happen if the token contains invalid characters, such as line
// breaks, or if the message has expired.
type InvalidAuthorizationMessageException struct {
Message *string
@ -218,10 +218,10 @@ func (e *PackedPolicyTooLargeException) ErrorFault() smithy.ErrorFault { return
// STS is not activated in the requested region for the account that is being
// asked to generate credentials. The account administrator must use the IAM
// console to activate STS in that region. For more information, see [Activating and Deactivating Amazon Web Services STS in an Amazon Web Services Region]in the IAM
// console to activate STS in that region. For more information, see [Activating and Deactivating STS in an Amazon Web Services Region]in the IAM
// User Guide.
//
// [Activating and Deactivating Amazon Web Services STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
// [Activating and Deactivating STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
type RegionDisabledException struct {
Message *string

View file

@ -70,6 +70,26 @@ func (m *validateOpAssumeRoleWithWebIdentity) HandleInitialize(ctx context.Conte
return next.HandleInitialize(ctx, in)
}
type validateOpAssumeRoot struct {
}
func (*validateOpAssumeRoot) ID() string {
return "OperationInputValidation"
}
func (m *validateOpAssumeRoot) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
out middleware.InitializeOutput, metadata middleware.Metadata, err error,
) {
input, ok := in.Parameters.(*AssumeRootInput)
if !ok {
return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters)
}
if err := validateOpAssumeRootInput(input); err != nil {
return out, metadata, err
}
return next.HandleInitialize(ctx, in)
}
type validateOpDecodeAuthorizationMessage struct {
}
@ -142,6 +162,10 @@ func addOpAssumeRoleWithWebIdentityValidationMiddleware(stack *middleware.Stack)
return stack.Initialize.Add(&validateOpAssumeRoleWithWebIdentity{}, middleware.After)
}
func addOpAssumeRootValidationMiddleware(stack *middleware.Stack) error {
return stack.Initialize.Add(&validateOpAssumeRoot{}, middleware.After)
}
func addOpDecodeAuthorizationMessageValidationMiddleware(stack *middleware.Stack) error {
return stack.Initialize.Add(&validateOpDecodeAuthorizationMessage{}, middleware.After)
}
@ -254,6 +278,24 @@ func validateOpAssumeRoleWithWebIdentityInput(v *AssumeRoleWithWebIdentityInput)
}
}
func validateOpAssumeRootInput(v *AssumeRootInput) error {
if v == nil {
return nil
}
invalidParams := smithy.InvalidParamsError{Context: "AssumeRootInput"}
if v.TargetPrincipal == nil {
invalidParams.Add(smithy.NewErrParamRequired("TargetPrincipal"))
}
if v.TaskPolicyArn == nil {
invalidParams.Add(smithy.NewErrParamRequired("TaskPolicyArn"))
}
if invalidParams.Len() > 0 {
return invalidParams
} else {
return nil
}
}
func validateOpDecodeAuthorizationMessageInput(v *DecodeAuthorizationMessageInput) error {
if v == nil {
return nil

View file

@ -1,3 +1,40 @@
# Release (2024-11-15)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/smithy-go`: v1.22.1
* **Bug Fix**: Fix failure to replace URI path segments when their names overlap.
# Release (2024-10-03)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/smithy-go`: v1.22.0
* **Feature**: Add HTTP client metrics.
# Release (2024-09-25)
## Module Highlights
* `github.com/aws/smithy-go/aws-http-auth`: [v1.0.0](aws-http-auth/CHANGELOG.md#v100-2024-09-25)
* **Release**: Initial release of module aws-http-auth, which implements generically consumable SigV4 and SigV4a request signing.
# Release (2024-09-19)
## General Highlights
* **Dependency Update**: Updated to the latest SDK module versions
## Module Highlights
* `github.com/aws/smithy-go`: v1.21.0
* **Feature**: Add tracing and metrics APIs, and builtin instrumentation for both, in generated clients.
* `github.com/aws/smithy-go/metrics/smithyotelmetrics`: [v1.0.0](metrics/smithyotelmetrics/CHANGELOG.md#v100-2024-09-19)
* **Release**: Initial release of `smithyotelmetrics` module, which is used to adapt an OpenTelemetry SDK meter provider to be used with Smithy clients.
* `github.com/aws/smithy-go/tracing/smithyoteltracing`: [v1.0.0](tracing/smithyoteltracing/CHANGELOG.md#v100-2024-09-19)
* **Release**: Initial release of `smithyoteltracing` module, which is used to adapt an OpenTelemetry SDK tracer provider to be used with Smithy clients.
# Release (2024-08-14)
## Module Highlights

View file

@ -22,33 +22,33 @@ func bufCap(b []byte, n int) []byte {
// replacePathElement replaces a single element in the path []byte.
// Escape is used to control whether the value will be escaped using Amazon path escape style.
func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) {
fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
// search for "{<key>}". If not found, search for the greedy version "{<key>+}". If none are found, return error
fieldBuf = bufCap(fieldBuf, len(key)+2) // { <key> }
fieldBuf = append(fieldBuf, uriTokenStart)
fieldBuf = append(fieldBuf, key...)
fieldBuf = append(fieldBuf, uriTokenStop)
start := bytes.Index(path, fieldBuf)
end := start + len(fieldBuf)
if start < 0 || len(path[end:]) == 0 {
// TODO what to do about error?
return path, fieldBuf, fmt.Errorf("invalid path index, start=%d,end=%d. %s", start, end, path)
}
encodeSep := true
if path[end] == uriTokenSkip {
// '+' token means do not escape slashes
if start < 0 {
fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
fieldBuf = append(fieldBuf, uriTokenStart)
fieldBuf = append(fieldBuf, key...)
fieldBuf = append(fieldBuf, uriTokenSkip)
fieldBuf = append(fieldBuf, uriTokenStop)
start = bytes.Index(path, fieldBuf)
if start < 0 {
return path, fieldBuf, fmt.Errorf("invalid path index, start=%d. %s", start, path)
}
encodeSep = false
end++
}
end := start + len(fieldBuf)
if escape {
val = EscapePath(val, encodeSep)
}
if path[end] != uriTokenStop {
return path, fieldBuf, fmt.Errorf("invalid path element, does not contain token stop, %s", path)
}
end++
fieldBuf = bufCap(fieldBuf, len(val))
fieldBuf = append(fieldBuf, val...)

View file

@ -3,4 +3,4 @@
package smithy
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.20.4"
const goModuleVersion = "1.22.1"

136
vendor/github.com/aws/smithy-go/metrics/metrics.go generated vendored Normal file
View file

@ -0,0 +1,136 @@
// Package metrics defines the metrics APIs used by Smithy clients.
package metrics
import (
"context"
"github.com/aws/smithy-go"
)
// MeterProvider is the entry point for creating a Meter.
type MeterProvider interface {
Meter(scope string, opts ...MeterOption) Meter
}
// MeterOption applies configuration to a Meter.
type MeterOption func(o *MeterOptions)
// MeterOptions represents configuration for a Meter.
type MeterOptions struct {
Properties smithy.Properties
}
// Meter is the entry point for creation of measurement instruments.
type Meter interface {
// integer/synchronous
Int64Counter(name string, opts ...InstrumentOption) (Int64Counter, error)
Int64UpDownCounter(name string, opts ...InstrumentOption) (Int64UpDownCounter, error)
Int64Gauge(name string, opts ...InstrumentOption) (Int64Gauge, error)
Int64Histogram(name string, opts ...InstrumentOption) (Int64Histogram, error)
// integer/asynchronous
Int64AsyncCounter(name string, callback Int64Callback, opts ...InstrumentOption) (AsyncInstrument, error)
Int64AsyncUpDownCounter(name string, callback Int64Callback, opts ...InstrumentOption) (AsyncInstrument, error)
Int64AsyncGauge(name string, callback Int64Callback, opts ...InstrumentOption) (AsyncInstrument, error)
// floating-point/synchronous
Float64Counter(name string, opts ...InstrumentOption) (Float64Counter, error)
Float64UpDownCounter(name string, opts ...InstrumentOption) (Float64UpDownCounter, error)
Float64Gauge(name string, opts ...InstrumentOption) (Float64Gauge, error)
Float64Histogram(name string, opts ...InstrumentOption) (Float64Histogram, error)
// floating-point/asynchronous
Float64AsyncCounter(name string, callback Float64Callback, opts ...InstrumentOption) (AsyncInstrument, error)
Float64AsyncUpDownCounter(name string, callback Float64Callback, opts ...InstrumentOption) (AsyncInstrument, error)
Float64AsyncGauge(name string, callback Float64Callback, opts ...InstrumentOption) (AsyncInstrument, error)
}
// InstrumentOption applies configuration to an instrument.
type InstrumentOption func(o *InstrumentOptions)
// InstrumentOptions represents configuration for an instrument.
type InstrumentOptions struct {
UnitLabel string
Description string
}
// Int64Counter measures a monotonically increasing int64 value.
type Int64Counter interface {
Add(context.Context, int64, ...RecordMetricOption)
}
// Int64UpDownCounter measures a fluctuating int64 value.
type Int64UpDownCounter interface {
Add(context.Context, int64, ...RecordMetricOption)
}
// Int64Gauge samples a discrete int64 value.
type Int64Gauge interface {
Sample(context.Context, int64, ...RecordMetricOption)
}
// Int64Histogram records multiple data points for an int64 value.
type Int64Histogram interface {
Record(context.Context, int64, ...RecordMetricOption)
}
// Float64Counter measures a monotonically increasing float64 value.
type Float64Counter interface {
Add(context.Context, float64, ...RecordMetricOption)
}
// Float64UpDownCounter measures a fluctuating float64 value.
type Float64UpDownCounter interface {
Add(context.Context, float64, ...RecordMetricOption)
}
// Float64Gauge samples a discrete float64 value.
type Float64Gauge interface {
Sample(context.Context, float64, ...RecordMetricOption)
}
// Float64Histogram records multiple data points for an float64 value.
type Float64Histogram interface {
Record(context.Context, float64, ...RecordMetricOption)
}
// AsyncInstrument is the universal handle returned for creation of all async
// instruments.
//
// Callers use the Stop() API to unregister the callback passed at instrument
// creation.
type AsyncInstrument interface {
Stop()
}
// Int64Callback describes a function invoked when an async int64 instrument is
// read.
type Int64Callback func(context.Context, Int64Observer)
// Int64Observer is the interface passed to async int64 instruments.
//
// Callers use the Observe() API of this interface to report metrics to the
// underlying collector.
type Int64Observer interface {
Observe(context.Context, int64, ...RecordMetricOption)
}
// Float64Callback describes a function invoked when an async float64
// instrument is read.
type Float64Callback func(context.Context, Float64Observer)
// Float64Observer is the interface passed to async int64 instruments.
//
// Callers use the Observe() API of this interface to report metrics to the
// underlying collector.
type Float64Observer interface {
Observe(context.Context, float64, ...RecordMetricOption)
}
// RecordMetricOption applies configuration to a recorded metric.
type RecordMetricOption func(o *RecordMetricOptions)
// RecordMetricOptions represents configuration for a recorded metric.
type RecordMetricOptions struct {
Properties smithy.Properties
}

67
vendor/github.com/aws/smithy-go/metrics/nop.go generated vendored Normal file
View file

@ -0,0 +1,67 @@
package metrics
import "context"
// NopMeterProvider is a no-op metrics implementation.
type NopMeterProvider struct{}
var _ MeterProvider = (*NopMeterProvider)(nil)
// Meter returns a meter which creates no-op instruments.
func (NopMeterProvider) Meter(string, ...MeterOption) Meter {
return nopMeter{}
}
type nopMeter struct{}
var _ Meter = (*nopMeter)(nil)
func (nopMeter) Int64Counter(string, ...InstrumentOption) (Int64Counter, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Int64UpDownCounter(string, ...InstrumentOption) (Int64UpDownCounter, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Int64Gauge(string, ...InstrumentOption) (Int64Gauge, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Int64Histogram(string, ...InstrumentOption) (Int64Histogram, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Int64AsyncCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Int64AsyncUpDownCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Int64AsyncGauge(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) {
return nopInstrument[int64]{}, nil
}
func (nopMeter) Float64Counter(string, ...InstrumentOption) (Float64Counter, error) {
return nopInstrument[float64]{}, nil
}
func (nopMeter) Float64UpDownCounter(string, ...InstrumentOption) (Float64UpDownCounter, error) {
return nopInstrument[float64]{}, nil
}
func (nopMeter) Float64Gauge(string, ...InstrumentOption) (Float64Gauge, error) {
return nopInstrument[float64]{}, nil
}
func (nopMeter) Float64Histogram(string, ...InstrumentOption) (Float64Histogram, error) {
return nopInstrument[float64]{}, nil
}
func (nopMeter) Float64AsyncCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) {
return nopInstrument[float64]{}, nil
}
func (nopMeter) Float64AsyncUpDownCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) {
return nopInstrument[float64]{}, nil
}
func (nopMeter) Float64AsyncGauge(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) {
return nopInstrument[float64]{}, nil
}
type nopInstrument[N any] struct{}
func (nopInstrument[N]) Add(context.Context, N, ...RecordMetricOption) {}
func (nopInstrument[N]) Sample(context.Context, N, ...RecordMetricOption) {}
func (nopInstrument[N]) Record(context.Context, N, ...RecordMetricOption) {}
func (nopInstrument[_]) Stop() {}

41
vendor/github.com/aws/smithy-go/middleware/context.go generated vendored Normal file
View file

@ -0,0 +1,41 @@
package middleware
import "context"
type (
serviceIDKey struct{}
operationNameKey struct{}
)
// WithServiceID adds a service ID to the context, scoped to middleware stack
// values.
//
// This API is called in the client runtime when bootstrapping an operation and
// should not typically be used directly.
func WithServiceID(parent context.Context, id string) context.Context {
return WithStackValue(parent, serviceIDKey{}, id)
}
// GetServiceID retrieves the service ID from the context. This is typically
// the service shape's name from its Smithy model. Service clients for specific
// systems (e.g. AWS SDK) may use an alternate designated value.
func GetServiceID(ctx context.Context) string {
id, _ := GetStackValue(ctx, serviceIDKey{}).(string)
return id
}
// WithOperationName adds the operation name to the context, scoped to
// middleware stack values.
//
// This API is called in the client runtime when bootstrapping an operation and
// should not typically be used directly.
func WithOperationName(parent context.Context, id string) context.Context {
return WithStackValue(parent, operationNameKey{}, id)
}
// GetOperationName retrieves the operation name from the context. This is
// typically the operation shape's name from its Smithy model.
func GetOperationName(ctx context.Context) string {
name, _ := GetStackValue(ctx, operationNameKey{}).(string)
return name
}

View file

@ -1,9 +1,11 @@
package smithy
import "maps"
// PropertiesReader provides an interface for reading metadata from the
// underlying metadata container.
type PropertiesReader interface {
Get(key interface{}) interface{}
Get(key any) any
}
// Properties provides storing and reading metadata values. Keys may be any
@ -12,14 +14,14 @@ type PropertiesReader interface {
// The zero value for a Properties instance is ready for reads/writes without
// any additional initialization.
type Properties struct {
values map[interface{}]interface{}
values map[any]any
}
// Get attempts to retrieve the value the key points to. Returns nil if the
// key was not found.
//
// Panics if key type is not comparable.
func (m *Properties) Get(key interface{}) interface{} {
func (m *Properties) Get(key any) any {
m.lazyInit()
return m.values[key]
}
@ -28,7 +30,7 @@ func (m *Properties) Get(key interface{}) interface{} {
// that key it will be replaced with the new value.
//
// Panics if the key type is not comparable.
func (m *Properties) Set(key, value interface{}) {
func (m *Properties) Set(key, value any) {
m.lazyInit()
m.values[key] = value
}
@ -36,7 +38,7 @@ func (m *Properties) Set(key, value interface{}) {
// Has returns whether the key exists in the metadata.
//
// Panics if the key type is not comparable.
func (m *Properties) Has(key interface{}) bool {
func (m *Properties) Has(key any) bool {
m.lazyInit()
_, ok := m.values[key]
return ok
@ -55,8 +57,13 @@ func (m *Properties) SetAll(other *Properties) {
}
}
// Values returns a shallow clone of the property set's values.
func (m *Properties) Values() map[any]any {
return maps.Clone(m.values)
}
func (m *Properties) lazyInit() {
if m.values == nil {
m.values = map[interface{}]interface{}{}
m.values = map[any]any{}
}
}

96
vendor/github.com/aws/smithy-go/tracing/context.go generated vendored Normal file
View file

@ -0,0 +1,96 @@
package tracing
import "context"
type (
operationTracerKey struct{}
spanLineageKey struct{}
)
// GetSpan returns the active trace Span on the context.
//
// The boolean in the return indicates whether a Span was actually in the
// context, but a no-op implementation will be returned if not, so callers
// can generally disregard the boolean unless they wish to explicitly confirm
// presence/absence of a Span.
func GetSpan(ctx context.Context) (Span, bool) {
lineage := getLineage(ctx)
if len(lineage) == 0 {
return nopSpan{}, false
}
return lineage[len(lineage)-1], true
}
// WithSpan sets the active trace Span on the context.
func WithSpan(parent context.Context, span Span) context.Context {
lineage := getLineage(parent)
if len(lineage) == 0 {
return context.WithValue(parent, spanLineageKey{}, []Span{span})
}
lineage = append(lineage, span)
return context.WithValue(parent, spanLineageKey{}, lineage)
}
// PopSpan pops the current Span off the context, setting the active Span on
// the returned Context back to its parent and returning the REMOVED one.
//
// PopSpan on a context with no active Span will return a no-op instance.
//
// This is mostly necessary for the runtime to manage base trace spans due to
// the wrapped-function nature of the middleware stack. End-users of Smithy
// clients SHOULD NOT generally be using this API.
func PopSpan(parent context.Context) (context.Context, Span) {
lineage := getLineage(parent)
if len(lineage) == 0 {
return parent, nopSpan{}
}
span := lineage[len(lineage)-1]
lineage = lineage[:len(lineage)-1]
return context.WithValue(parent, spanLineageKey{}, lineage), span
}
func getLineage(ctx context.Context) []Span {
v := ctx.Value(spanLineageKey{})
if v == nil {
return nil
}
return v.([]Span)
}
// GetOperationTracer returns the embedded operation-scoped Tracer on a
// Context.
//
// The boolean in the return indicates whether a Tracer was actually in the
// context, but a no-op implementation will be returned if not, so callers
// can generally disregard the boolean unless they wish to explicitly confirm
// presence/absence of a Tracer.
func GetOperationTracer(ctx context.Context) (Tracer, bool) {
v := ctx.Value(operationTracerKey{})
if v == nil {
return nopTracer{}, false
}
return v.(Tracer), true
}
// WithOperationTracer returns a child Context embedding the given Tracer.
//
// The runtime will use this embed a scoped tracer for client operations,
// Smithy/SDK client callers DO NOT need to do this explicitly.
func WithOperationTracer(parent context.Context, tracer Tracer) context.Context {
return context.WithValue(parent, operationTracerKey{}, tracer)
}
// StartSpan is a convenience API for creating tracing Spans from a Context.
//
// StartSpan uses the operation-scoped Tracer, previously stored using
// [WithOperationTracer], to start the Span. If a Tracer has not been embedded
// the returned Span will be a no-op implementation.
func StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) {
tracer, _ := GetOperationTracer(ctx)
return tracer.StartSpan(ctx, name, opts...)
}

32
vendor/github.com/aws/smithy-go/tracing/nop.go generated vendored Normal file
View file

@ -0,0 +1,32 @@
package tracing
import "context"
// NopTracerProvider is a no-op tracing implementation.
type NopTracerProvider struct{}
var _ TracerProvider = (*NopTracerProvider)(nil)
// Tracer returns a tracer which creates no-op spans.
func (NopTracerProvider) Tracer(string, ...TracerOption) Tracer {
return nopTracer{}
}
type nopTracer struct{}
var _ Tracer = (*nopTracer)(nil)
func (nopTracer) StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) {
return ctx, nopSpan{}
}
type nopSpan struct{}
var _ Span = (*nopSpan)(nil)
func (nopSpan) Name() string { return "" }
func (nopSpan) Context() SpanContext { return SpanContext{} }
func (nopSpan) AddEvent(string, ...EventOption) {}
func (nopSpan) SetProperty(any, any) {}
func (nopSpan) SetStatus(SpanStatus) {}
func (nopSpan) End() {}

95
vendor/github.com/aws/smithy-go/tracing/tracing.go generated vendored Normal file
View file

@ -0,0 +1,95 @@
// Package tracing defines tracing APIs to be used by Smithy clients.
package tracing
import (
"context"
"github.com/aws/smithy-go"
)
// SpanStatus records the "success" state of an observed span.
type SpanStatus int
// Enumeration of SpanStatus.
const (
SpanStatusUnset SpanStatus = iota
SpanStatusOK
SpanStatusError
)
// SpanKind indicates the nature of the work being performed.
type SpanKind int
// Enumeration of SpanKind.
const (
SpanKindInternal SpanKind = iota
SpanKindClient
SpanKindServer
SpanKindProducer
SpanKindConsumer
)
// TracerProvider is the entry point for creating client traces.
type TracerProvider interface {
Tracer(scope string, opts ...TracerOption) Tracer
}
// TracerOption applies configuration to a tracer.
type TracerOption func(o *TracerOptions)
// TracerOptions represent configuration for tracers.
type TracerOptions struct {
Properties smithy.Properties
}
// Tracer is the entry point for creating observed client Spans.
//
// Spans created by tracers propagate by existing on the Context. Consumers of
// the API can use [GetSpan] to pull the active Span from a Context.
//
// Creation of child Spans is implicit through Context persistence. If
// CreateSpan is called with a Context that holds a Span, the result will be a
// child of that Span.
type Tracer interface {
StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span)
}
// SpanOption applies configuration to a span.
type SpanOption func(o *SpanOptions)
// SpanOptions represent configuration for span events.
type SpanOptions struct {
Kind SpanKind
Properties smithy.Properties
}
// Span records a conceptually individual unit of work that takes place in a
// Smithy client operation.
type Span interface {
Name() string
Context() SpanContext
AddEvent(name string, opts ...EventOption)
SetStatus(status SpanStatus)
SetProperty(k, v any)
End()
}
// EventOption applies configuration to a span event.
type EventOption func(o *EventOptions)
// EventOptions represent configuration for span events.
type EventOptions struct {
Properties smithy.Properties
}
// SpanContext uniquely identifies a Span.
type SpanContext struct {
TraceID string
SpanID string
IsRemote bool
}
// IsValid is true when a span has nonzero trace and span IDs.
func (ctx *SpanContext) IsValid() bool {
return len(ctx.TraceID) != 0 && len(ctx.SpanID) != 0
}

View file

@ -6,7 +6,9 @@ import (
"net/http"
smithy "github.com/aws/smithy-go"
"github.com/aws/smithy-go/metrics"
"github.com/aws/smithy-go/middleware"
"github.com/aws/smithy-go/tracing"
)
// ClientDo provides the interface for custom HTTP client implementations.
@ -27,13 +29,30 @@ func (fn ClientDoFunc) Do(r *http.Request) (*http.Response, error) {
// implementation is http.Client.
type ClientHandler struct {
client ClientDo
Meter metrics.Meter // For HTTP client metrics.
}
// NewClientHandler returns an initialized middleware handler for the client.
//
// Deprecated: Use [NewClientHandlerWithOptions].
func NewClientHandler(client ClientDo) ClientHandler {
return ClientHandler{
return NewClientHandlerWithOptions(client)
}
// NewClientHandlerWithOptions returns an initialized middleware handler for the client
// with applied options.
func NewClientHandlerWithOptions(client ClientDo, opts ...func(*ClientHandler)) ClientHandler {
h := ClientHandler{
client: client,
}
for _, opt := range opts {
opt(&h)
}
if h.Meter == nil {
h.Meter = metrics.NopMeterProvider{}.Meter("")
}
return h
}
// Handle implements the middleware Handler interface, that will invoke the
@ -42,6 +61,14 @@ func NewClientHandler(client ClientDo) ClientHandler {
func (c ClientHandler) Handle(ctx context.Context, input interface{}) (
out interface{}, metadata middleware.Metadata, err error,
) {
ctx, span := tracing.StartSpan(ctx, "DoHTTPRequest")
defer span.End()
ctx, client, err := withMetrics(ctx, c.client, c.Meter)
if err != nil {
return nil, metadata, fmt.Errorf("instrument with HTTP metrics: %w", err)
}
req, ok := input.(*Request)
if !ok {
return nil, metadata, fmt.Errorf("expect Smithy http.Request value as input, got unsupported type %T", input)
@ -52,7 +79,17 @@ func (c ClientHandler) Handle(ctx context.Context, input interface{}) (
return nil, metadata, err
}
resp, err := c.client.Do(builtRequest)
span.SetProperty("http.method", req.Method)
span.SetProperty("http.request_content_length", -1) // at least indicate unknown
length, ok, err := req.StreamLength()
if err != nil {
return nil, metadata, err
}
if ok {
span.SetProperty("http.request_content_length", length)
}
resp, err := client.Do(builtRequest)
if resp == nil {
// Ensure a http response value is always present to prevent unexpected
// panics.
@ -79,6 +116,10 @@ func (c ClientHandler) Handle(ctx context.Context, input interface{}) (
_ = builtRequest.Body.Close()
}
span.SetProperty("net.protocol.version", fmt.Sprintf("%d.%d", resp.ProtoMajor, resp.ProtoMinor))
span.SetProperty("http.status_code", resp.StatusCode)
span.SetProperty("http.response_content_length", resp.ContentLength)
return &Response{Response: resp}, metadata, err
}

View file

@ -0,0 +1,184 @@
package http
import (
"context"
"crypto/tls"
"net/http"
"net/http/httptrace"
"time"
"github.com/aws/smithy-go/metrics"
)
var now = time.Now
// withMetrics instruments an HTTP client and context to collect HTTP metrics.
func withMetrics(parent context.Context, client ClientDo, meter metrics.Meter) (
context.Context, ClientDo, error,
) {
hm, err := newHTTPMetrics(meter)
if err != nil {
return nil, nil, err
}
ctx := httptrace.WithClientTrace(parent, &httptrace.ClientTrace{
DNSStart: hm.DNSStart,
ConnectStart: hm.ConnectStart,
TLSHandshakeStart: hm.TLSHandshakeStart,
GotConn: hm.GotConn(parent),
PutIdleConn: hm.PutIdleConn(parent),
ConnectDone: hm.ConnectDone(parent),
DNSDone: hm.DNSDone(parent),
TLSHandshakeDone: hm.TLSHandshakeDone(parent),
GotFirstResponseByte: hm.GotFirstResponseByte(parent),
})
return ctx, &timedClientDo{client, hm}, nil
}
type timedClientDo struct {
ClientDo
hm *httpMetrics
}
func (c *timedClientDo) Do(r *http.Request) (*http.Response, error) {
c.hm.doStart = now()
resp, err := c.ClientDo.Do(r)
c.hm.DoRequestDuration.Record(r.Context(), elapsed(c.hm.doStart))
return resp, err
}
type httpMetrics struct {
DNSLookupDuration metrics.Float64Histogram // client.http.connections.dns_lookup_duration
ConnectDuration metrics.Float64Histogram // client.http.connections.acquire_duration
TLSHandshakeDuration metrics.Float64Histogram // client.http.connections.tls_handshake_duration
ConnectionUsage metrics.Int64UpDownCounter // client.http.connections.usage
DoRequestDuration metrics.Float64Histogram // client.http.do_request_duration
TimeToFirstByte metrics.Float64Histogram // client.http.time_to_first_byte
doStart time.Time
dnsStart time.Time
connectStart time.Time
tlsStart time.Time
}
func newHTTPMetrics(meter metrics.Meter) (*httpMetrics, error) {
hm := &httpMetrics{}
var err error
hm.DNSLookupDuration, err = meter.Float64Histogram("client.http.connections.dns_lookup_duration", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = "The time it takes a request to perform DNS lookup."
})
if err != nil {
return nil, err
}
hm.ConnectDuration, err = meter.Float64Histogram("client.http.connections.acquire_duration", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = "The time it takes a request to acquire a connection."
})
if err != nil {
return nil, err
}
hm.TLSHandshakeDuration, err = meter.Float64Histogram("client.http.connections.tls_handshake_duration", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = "The time it takes an HTTP request to perform the TLS handshake."
})
if err != nil {
return nil, err
}
hm.ConnectionUsage, err = meter.Int64UpDownCounter("client.http.connections.usage", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "{connection}"
o.Description = "Current state of connections pool."
})
if err != nil {
return nil, err
}
hm.DoRequestDuration, err = meter.Float64Histogram("client.http.do_request_duration", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = "Time spent performing an entire HTTP transaction."
})
if err != nil {
return nil, err
}
hm.TimeToFirstByte, err = meter.Float64Histogram("client.http.time_to_first_byte", func(o *metrics.InstrumentOptions) {
o.UnitLabel = "s"
o.Description = "Time from start of transaction to when the first response byte is available."
})
if err != nil {
return nil, err
}
return hm, nil
}
func (m *httpMetrics) DNSStart(httptrace.DNSStartInfo) {
m.dnsStart = now()
}
func (m *httpMetrics) ConnectStart(string, string) {
m.connectStart = now()
}
func (m *httpMetrics) TLSHandshakeStart() {
m.tlsStart = now()
}
func (m *httpMetrics) GotConn(ctx context.Context) func(httptrace.GotConnInfo) {
return func(httptrace.GotConnInfo) {
m.addConnAcquired(ctx, 1)
}
}
func (m *httpMetrics) PutIdleConn(ctx context.Context) func(error) {
return func(error) {
m.addConnAcquired(ctx, -1)
}
}
func (m *httpMetrics) DNSDone(ctx context.Context) func(httptrace.DNSDoneInfo) {
return func(httptrace.DNSDoneInfo) {
m.DNSLookupDuration.Record(ctx, elapsed(m.dnsStart))
}
}
func (m *httpMetrics) ConnectDone(ctx context.Context) func(string, string, error) {
return func(string, string, error) {
m.ConnectDuration.Record(ctx, elapsed(m.connectStart))
}
}
func (m *httpMetrics) TLSHandshakeDone(ctx context.Context) func(tls.ConnectionState, error) {
return func(tls.ConnectionState, error) {
m.TLSHandshakeDuration.Record(ctx, elapsed(m.tlsStart))
}
}
func (m *httpMetrics) GotFirstResponseByte(ctx context.Context) func() {
return func() {
m.TimeToFirstByte.Record(ctx, elapsed(m.doStart))
}
}
func (m *httpMetrics) addConnAcquired(ctx context.Context, incr int64) {
m.ConnectionUsage.Add(ctx, incr, func(o *metrics.RecordMetricOptions) {
o.Properties.Set("state", "acquired")
})
}
// Not used: it is recommended to track acquired vs idle conn, but we can't
// determine when something is truly idle with the current HTTP client hooks
// available to us.
func (m *httpMetrics) addConnIdle(ctx context.Context, incr int64) {
m.ConnectionUsage.Add(ctx, incr, func(o *metrics.RecordMetricOptions) {
o.Properties.Set("state", "idle")
})
}
func elapsed(start time.Time) float64 {
end := now()
elapsed := end.Sub(start)
return float64(elapsed) / 1e9
}

View file

@ -26,12 +26,13 @@ import (
"archive/tar"
"bytes"
"compress/gzip"
"crypto/rand"
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
"io"
"math/rand"
"math/big"
"os"
"path/filepath"
"reflect"
@ -45,10 +46,6 @@ import (
digest "github.com/opencontainers/go-digest"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// TestingController is Compression with some helper methods necessary for testing.
type TestingController interface {
Compression
@ -920,9 +917,11 @@ func checkVerifyInvalidTOCEntryFail(filename string) check {
}
if sampleEntry == nil {
t.Fatalf("TOC must contain at least one regfile or chunk entry other than the rewrite target")
return
}
if targetEntry == nil {
t.Fatalf("rewrite target not found")
return
}
targetEntry.Offset = sampleEntry.Offset
},
@ -2291,7 +2290,11 @@ var runes = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX
func randomContents(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = runes[rand.Intn(len(runes))]
bi, err := rand.Int(rand.Reader, big.NewInt(int64(len(runes))))
if err != nil {
panic(err)
}
b[i] = runes[int(bi.Int64())]
}
return string(b)
}

View file

@ -18,3 +18,9 @@ As a containerd sub-project, you will find the:
* and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)
information in our [`containerd/project`](https://github.com/containerd/project) repository.
## Optional
By default, support for gogoproto is available along side the standard Google
protobuf types.
You can choose to leave gogo support out by using the `!no_gogo` build tag.

View file

@ -24,7 +24,6 @@ import (
"reflect"
"sync"
gogoproto "github.com/gogo/protobuf/proto"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/known/anypb"
@ -33,8 +32,16 @@ import (
var (
mu sync.RWMutex
registry = make(map[reflect.Type]string)
handlers []handler
)
type handler interface {
Marshaller(interface{}) func() ([]byte, error)
Unmarshaller(interface{}) func([]byte) error
TypeURL(interface{}) string
GetType(url string) (reflect.Type, bool)
}
// Definitions of common error types used throughout typeurl.
//
// These error types are used with errors.Wrap and errors.Wrapf to add context
@ -112,9 +119,12 @@ func TypeURL(v interface{}) (string, error) {
switch t := v.(type) {
case proto.Message:
return string(t.ProtoReflect().Descriptor().FullName()), nil
case gogoproto.Message:
return gogoproto.MessageName(t), nil
default:
for _, h := range handlers {
if u := h.TypeURL(v); u != "" {
return u, nil
}
}
return "", fmt.Errorf("type %s: %w", reflect.TypeOf(v), ErrNotFound)
}
}
@ -149,12 +159,19 @@ func MarshalAny(v interface{}) (Any, error) {
marshal = func(v interface{}) ([]byte, error) {
return proto.Marshal(t)
}
case gogoproto.Message:
marshal = func(v interface{}) ([]byte, error) {
return gogoproto.Marshal(t)
}
default:
marshal = json.Marshal
for _, h := range handlers {
if m := h.Marshaller(v); m != nil {
marshal = func(v interface{}) ([]byte, error) {
return m()
}
break
}
}
if marshal == nil {
marshal = json.Marshal
}
}
url, err := TypeURL(v)
@ -223,13 +240,13 @@ func MarshalAnyToProto(from interface{}) (*anypb.Any, error) {
}
func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) {
t, err := getTypeByUrl(typeURL)
t, isProto, err := getTypeByUrl(typeURL)
if err != nil {
return nil, err
}
if v == nil {
v = reflect.New(t.t).Interface()
v = reflect.New(t).Interface()
} else {
// Validate interface type provided by client
vURL, err := TypeURL(v)
@ -241,51 +258,45 @@ func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error)
}
}
if t.isProto {
switch t := v.(type) {
case proto.Message:
err = proto.Unmarshal(value, t)
case gogoproto.Message:
err = gogoproto.Unmarshal(value, t)
if isProto {
pm, ok := v.(proto.Message)
if ok {
return v, proto.Unmarshal(value, pm)
}
for _, h := range handlers {
if unmarshal := h.Unmarshaller(v); unmarshal != nil {
return v, unmarshal(value)
}
}
} else {
err = json.Unmarshal(value, v)
}
return v, err
// fallback to json unmarshaller
return v, json.Unmarshal(value, v)
}
type urlType struct {
t reflect.Type
isProto bool
}
func getTypeByUrl(url string) (urlType, error) {
func getTypeByUrl(url string) (_ reflect.Type, isProto bool, _ error) {
mu.RLock()
for t, u := range registry {
if u == url {
mu.RUnlock()
return urlType{
t: t,
}, nil
return t, false, nil
}
}
mu.RUnlock()
// fallback to proto registry
t := gogoproto.MessageType(url)
if t != nil {
return urlType{
// get the underlying Elem because proto returns a pointer to the type
t: t.Elem(),
isProto: true,
}, nil
}
mt, err := protoregistry.GlobalTypes.FindMessageByURL(url)
if err != nil {
return urlType{}, fmt.Errorf("type with url %s: %w", url, ErrNotFound)
if errors.Is(err, protoregistry.NotFound) {
for _, h := range handlers {
if t, isProto := h.GetType(url); t != nil {
return t, isProto, nil
}
}
}
return nil, false, fmt.Errorf("type with url %s: %w", url, ErrNotFound)
}
empty := mt.New().Interface()
return urlType{t: reflect.TypeOf(empty).Elem(), isProto: true}, nil
return reflect.TypeOf(empty).Elem(), true, nil
}
func tryDereference(v interface{}) reflect.Type {

68
vendor/github.com/containerd/typeurl/v2/types_gogo.go generated vendored Normal file
View file

@ -0,0 +1,68 @@
//go:build !no_gogo
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package typeurl
import (
"reflect"
gogoproto "github.com/gogo/protobuf/proto"
)
func init() {
handlers = append(handlers, gogoHandler{})
}
type gogoHandler struct{}
func (gogoHandler) Marshaller(v interface{}) func() ([]byte, error) {
pm, ok := v.(gogoproto.Message)
if !ok {
return nil
}
return func() ([]byte, error) {
return gogoproto.Marshal(pm)
}
}
func (gogoHandler) Unmarshaller(v interface{}) func([]byte) error {
pm, ok := v.(gogoproto.Message)
if !ok {
return nil
}
return func(dt []byte) error {
return gogoproto.Unmarshal(dt, pm)
}
}
func (gogoHandler) TypeURL(v interface{}) string {
pm, ok := v.(gogoproto.Message)
if !ok {
return ""
}
return gogoproto.MessageName(pm)
}
func (gogoHandler) GetType(url string) (reflect.Type, bool) {
t := gogoproto.MessageType(url)
if t == nil {
return nil, false
}
return t.Elem(), true
}

View file

@ -109,7 +109,7 @@ func (c *copier) copySingleImage(ctx context.Context, unparsedImage *image.Unpar
}
}
if err := checkImageDestinationForCurrentRuntime(ctx, c.options.DestinationCtx, src, c.dest); err != nil {
if err := prepareImageConfigForDest(ctx, c.options.DestinationCtx, src, c.dest); err != nil {
return copySingleImageResult{}, err
}
@ -316,12 +316,15 @@ func (c *copier) copySingleImage(ctx context.Context, unparsedImage *image.Unpar
return res, nil
}
// checkImageDestinationForCurrentRuntime enforces dest.MustMatchRuntimeOS, if necessary.
func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.SystemContext, src types.Image, dest types.ImageDestination) error {
// prepareImageConfigForDest enforces dest.MustMatchRuntimeOS and handles dest.NoteOriginalOCIConfig, if necessary.
func prepareImageConfigForDest(ctx context.Context, sys *types.SystemContext, src types.Image, dest private.ImageDestination) error {
ociConfig, configErr := src.OCIConfig(ctx)
// Do not fail on configErr here, this might be an artifact
// and maybe nothing needs this to be a container image and to process the config.
if dest.MustMatchRuntimeOS() {
c, err := src.OCIConfig(ctx)
if err != nil {
return fmt.Errorf("parsing image configuration: %w", err)
if configErr != nil {
return fmt.Errorf("parsing image configuration: %w", configErr)
}
wantedPlatforms := platform.WantedPlatforms(sys)
@ -331,7 +334,7 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst
// For a transitional period, this might trigger warnings because the Variant
// field was added to OCI config only recently. If this turns out to be too noisy,
// revert this check to only look for (OS, Architecture).
if platform.MatchesPlatform(c.Platform, wantedPlatform) {
if platform.MatchesPlatform(ociConfig.Platform, wantedPlatform) {
match = true
break
}
@ -339,9 +342,14 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst
}
if !match {
logrus.Infof("Image operating system mismatch: image uses OS %q+architecture %q+%q, expecting one of %q",
c.OS, c.Architecture, c.Variant, strings.Join(options.list, ", "))
ociConfig.OS, ociConfig.Architecture, ociConfig.Variant, strings.Join(options.list, ", "))
}
}
if err := dest.NoteOriginalOCIConfig(ociConfig, configErr); err != nil {
return err
}
return nil
}

View file

@ -29,6 +29,7 @@ var ErrNotContainerImageDir = errors.New("not a containers image directory, don'
type dirImageDestination struct {
impl.Compat
impl.PropertyMethodsInitialize
stubs.IgnoresOriginalOCIConfig
stubs.NoPutBlobPartialInitialize
stubs.AlwaysSupportsSignatures

View file

@ -3,6 +3,7 @@ package daemon
import (
"net/http"
"path/filepath"
"time"
"github.com/containers/image/v5/types"
dockerclient "github.com/docker/docker/client"
@ -47,6 +48,7 @@ func newDockerClient(sys *types.SystemContext) (*dockerclient.Client, error) {
}
switch serverURL.Scheme {
case "unix": // Nothing
case "npipe": // Nothing
case "http":
hc := httpConfig()
opts = append(opts, dockerclient.WithHTTPClient(hc))
@ -82,6 +84,11 @@ func tlsConfig(sys *types.SystemContext) (*http.Client, error) {
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: tlsc,
// In general we want to follow docker/daemon/client.defaultHTTPClient , as long as it doesnt affect compatibility.
// These idle connection limits really only apply to long-running clients, which is not our case here;
// we include the same values purely for symmetry.
MaxIdleConns: 6,
IdleConnTimeout: 30 * time.Second,
},
CheckRedirect: dockerclient.CheckRedirect,
}, nil
@ -92,6 +99,11 @@ func httpConfig() *http.Client {
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: nil,
// In general we want to follow docker/daemon/client.defaultHTTPClient , as long as it doesnt affect compatibility.
// These idle connection limits really only apply to long-running clients, which is not our case here;
// we include the same values purely for symmetry.
MaxIdleConns: 6,
IdleConnTimeout: 30 * time.Second,
},
CheckRedirect: dockerclient.CheckRedirect,
}

View file

@ -24,7 +24,6 @@ import (
"slices"
"github.com/docker/distribution/registry/api/errcode"
dockerChallenge "github.com/docker/distribution/registry/client/auth/challenge"
)
// errNoErrorsInBody is returned when an HTTP response body parses to an empty
@ -114,10 +113,11 @@ func mergeErrors(err1, err2 error) error {
// UnexpectedHTTPStatusError returned for response code outside of expected
// range.
func handleErrorResponse(resp *http.Response) error {
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
switch {
case resp.StatusCode == http.StatusUnauthorized:
// Check for OAuth errors within the `WWW-Authenticate` header first
// See https://tools.ietf.org/html/rfc6750#section-3
for _, c := range dockerChallenge.ResponseChallenges(resp) {
for _, c := range parseAuthHeader(resp.Header) {
if c.Scheme == "bearer" {
var err errcode.Error
// codes defined at https://tools.ietf.org/html/rfc6750#section-3.1
@ -138,6 +138,8 @@ func handleErrorResponse(resp *http.Response) error {
return mergeErrors(err, parseHTTPErrorResponse(resp.StatusCode, resp.Body))
}
}
fallthrough
case resp.StatusCode >= 400 && resp.StatusCode < 500:
err := parseHTTPErrorResponse(resp.StatusCode, resp.Body)
if uErr, ok := err.(*unexpectedHTTPResponseError); ok && resp.StatusCode == 401 {
return errcode.ErrorCodeUnauthorized.WithDetail(uErr.Response)

View file

@ -1056,6 +1056,15 @@ func (c *dockerClient) getBlob(ctx context.Context, ref dockerReference, info ty
func (c *dockerClient) getOCIDescriptorContents(ctx context.Context, ref dockerReference, desc imgspecv1.Descriptor, maxSize int, cache types.BlobInfoCache) ([]byte, error) {
// Note that this copies all kinds of attachments: attestations, and whatever else is there,
// not just signatures. We leave the signature consumers to decide based on the MIME type.
if err := desc.Digest.Validate(); err != nil { // .Algorithm() might panic without this check
return nil, fmt.Errorf("invalid digest %q: %w", desc.Digest.String(), err)
}
digestAlgorithm := desc.Digest.Algorithm()
if !digestAlgorithm.Available() {
return nil, fmt.Errorf("invalid digest %q: unsupported digest algorithm %q", desc.Digest.String(), digestAlgorithm.String())
}
reader, _, err := c.getBlob(ctx, ref, manifest.BlobInfoFromOCI1Descriptor(desc), cache)
if err != nil {
return nil, err
@ -1065,6 +1074,10 @@ func (c *dockerClient) getOCIDescriptorContents(ctx context.Context, ref dockerR
if err != nil {
return nil, fmt.Errorf("reading blob %s in %s: %w", desc.Digest.String(), ref.ref.Name(), err)
}
actualDigest := digestAlgorithm.FromBytes(payload)
if actualDigest != desc.Digest {
return nil, fmt.Errorf("digest mismatch, expected %q, got %q", desc.Digest.String(), actualDigest.String())
}
return payload, nil
}

Some files were not shown because too many files have changed in this diff Show more