1package config
  2
  3import (
  4	"context"
  5	"io"
  6	"net/http"
  7
  8	"github.com/aws/aws-sdk-go-v2/aws"
  9	"github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
 10	"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
 11	"github.com/aws/aws-sdk-go-v2/credentials/processcreds"
 12	"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
 13	"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
 14	"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
 15	smithybearer "github.com/aws/smithy-go/auth/bearer"
 16	"github.com/aws/smithy-go/logging"
 17	"github.com/aws/smithy-go/middleware"
 18)
 19
 20// sharedConfigProfileProvider provides access to the shared config profile
 21// name external configuration value.
 22type sharedConfigProfileProvider interface {
 23	getSharedConfigProfile(ctx context.Context) (string, bool, error)
 24}
 25
 26// getSharedConfigProfile searches the configs for a sharedConfigProfileProvider
 27// and returns the value if found. Returns an error if a provider fails before a
 28// value is found.
 29func getSharedConfigProfile(ctx context.Context, configs configs) (value string, found bool, err error) {
 30	for _, cfg := range configs {
 31		if p, ok := cfg.(sharedConfigProfileProvider); ok {
 32			value, found, err = p.getSharedConfigProfile(ctx)
 33			if err != nil || found {
 34				break
 35			}
 36		}
 37	}
 38	return
 39}
 40
 41// sharedConfigFilesProvider provides access to the shared config filesnames
 42// external configuration value.
 43type sharedConfigFilesProvider interface {
 44	getSharedConfigFiles(ctx context.Context) ([]string, bool, error)
 45}
 46
 47// getSharedConfigFiles searches the configs for a sharedConfigFilesProvider
 48// and returns the value if found. Returns an error if a provider fails before a
 49// value is found.
 50func getSharedConfigFiles(ctx context.Context, configs configs) (value []string, found bool, err error) {
 51	for _, cfg := range configs {
 52		if p, ok := cfg.(sharedConfigFilesProvider); ok {
 53			value, found, err = p.getSharedConfigFiles(ctx)
 54			if err != nil || found {
 55				break
 56			}
 57		}
 58	}
 59
 60	return
 61}
 62
 63// sharedCredentialsFilesProvider provides access to the shared credentials filesnames
 64// external configuration value.
 65type sharedCredentialsFilesProvider interface {
 66	getSharedCredentialsFiles(ctx context.Context) ([]string, bool, error)
 67}
 68
 69// getSharedCredentialsFiles searches the configs for a sharedCredentialsFilesProvider
 70// and returns the value if found. Returns an error if a provider fails before a
 71// value is found.
 72func getSharedCredentialsFiles(ctx context.Context, configs configs) (value []string, found bool, err error) {
 73	for _, cfg := range configs {
 74		if p, ok := cfg.(sharedCredentialsFilesProvider); ok {
 75			value, found, err = p.getSharedCredentialsFiles(ctx)
 76			if err != nil || found {
 77				break
 78			}
 79		}
 80	}
 81
 82	return
 83}
 84
 85// customCABundleProvider provides access to the custom CA bundle PEM bytes.
 86type customCABundleProvider interface {
 87	getCustomCABundle(ctx context.Context) (io.Reader, bool, error)
 88}
 89
 90// getCustomCABundle searches the configs for a customCABundleProvider
 91// and returns the value if found. Returns an error if a provider fails before a
 92// value is found.
 93func getCustomCABundle(ctx context.Context, configs configs) (value io.Reader, found bool, err error) {
 94	for _, cfg := range configs {
 95		if p, ok := cfg.(customCABundleProvider); ok {
 96			value, found, err = p.getCustomCABundle(ctx)
 97			if err != nil || found {
 98				break
 99			}
100		}
101	}
102
103	return
104}
105
106// regionProvider provides access to the region external configuration value.
107type regionProvider interface {
108	getRegion(ctx context.Context) (string, bool, error)
109}
110
111// getRegion searches the configs for a regionProvider and returns the value
112// if found. Returns an error if a provider fails before a value is found.
113func getRegion(ctx context.Context, configs configs) (value string, found bool, err error) {
114	for _, cfg := range configs {
115		if p, ok := cfg.(regionProvider); ok {
116			value, found, err = p.getRegion(ctx)
117			if err != nil || found {
118				break
119			}
120		}
121	}
122	return
123}
124
125// IgnoreConfiguredEndpointsProvider is needed to search for all providers
126// that provide a flag to disable configured endpoints.
127type IgnoreConfiguredEndpointsProvider interface {
128	GetIgnoreConfiguredEndpoints(ctx context.Context) (bool, bool, error)
129}
130
131// GetIgnoreConfiguredEndpoints is used in knowing when to disable configured
132// endpoints feature.
133func GetIgnoreConfiguredEndpoints(ctx context.Context, configs []interface{}) (value bool, found bool, err error) {
134	for _, cfg := range configs {
135		if p, ok := cfg.(IgnoreConfiguredEndpointsProvider); ok {
136			value, found, err = p.GetIgnoreConfiguredEndpoints(ctx)
137			if err != nil || found {
138				break
139			}
140		}
141	}
142	return
143}
144
145type baseEndpointProvider interface {
146	getBaseEndpoint(ctx context.Context) (string, bool, error)
147}
148
149func getBaseEndpoint(ctx context.Context, configs configs) (value string, found bool, err error) {
150	for _, cfg := range configs {
151		if p, ok := cfg.(baseEndpointProvider); ok {
152			value, found, err = p.getBaseEndpoint(ctx)
153			if err != nil || found {
154				break
155			}
156		}
157	}
158	return
159}
160
161type servicesObjectProvider interface {
162	getServicesObject(ctx context.Context) (map[string]map[string]string, bool, error)
163}
164
165func getServicesObject(ctx context.Context, configs configs) (value map[string]map[string]string, found bool, err error) {
166	for _, cfg := range configs {
167		if p, ok := cfg.(servicesObjectProvider); ok {
168			value, found, err = p.getServicesObject(ctx)
169			if err != nil || found {
170				break
171			}
172		}
173	}
174	return
175}
176
177// appIDProvider provides access to the sdk app ID value
178type appIDProvider interface {
179	getAppID(ctx context.Context) (string, bool, error)
180}
181
182func getAppID(ctx context.Context, configs configs) (value string, found bool, err error) {
183	for _, cfg := range configs {
184		if p, ok := cfg.(appIDProvider); ok {
185			value, found, err = p.getAppID(ctx)
186			if err != nil || found {
187				break
188			}
189		}
190	}
191	return
192}
193
194// disableRequestCompressionProvider provides access to the DisableRequestCompression
195type disableRequestCompressionProvider interface {
196	getDisableRequestCompression(context.Context) (bool, bool, error)
197}
198
199func getDisableRequestCompression(ctx context.Context, configs configs) (value bool, found bool, err error) {
200	for _, cfg := range configs {
201		if p, ok := cfg.(disableRequestCompressionProvider); ok {
202			value, found, err = p.getDisableRequestCompression(ctx)
203			if err != nil || found {
204				break
205			}
206		}
207	}
208	return
209}
210
211// requestMinCompressSizeBytesProvider provides access to the MinCompressSizeBytes
212type requestMinCompressSizeBytesProvider interface {
213	getRequestMinCompressSizeBytes(context.Context) (int64, bool, error)
214}
215
216func getRequestMinCompressSizeBytes(ctx context.Context, configs configs) (value int64, found bool, err error) {
217	for _, cfg := range configs {
218		if p, ok := cfg.(requestMinCompressSizeBytesProvider); ok {
219			value, found, err = p.getRequestMinCompressSizeBytes(ctx)
220			if err != nil || found {
221				break
222			}
223		}
224	}
225	return
226}
227
228// accountIDEndpointModeProvider provides access to the AccountIDEndpointMode
229type accountIDEndpointModeProvider interface {
230	getAccountIDEndpointMode(context.Context) (aws.AccountIDEndpointMode, bool, error)
231}
232
233func getAccountIDEndpointMode(ctx context.Context, configs configs) (value aws.AccountIDEndpointMode, found bool, err error) {
234	for _, cfg := range configs {
235		if p, ok := cfg.(accountIDEndpointModeProvider); ok {
236			value, found, err = p.getAccountIDEndpointMode(ctx)
237			if err != nil || found {
238				break
239			}
240		}
241	}
242	return
243}
244
245// ec2IMDSRegionProvider provides access to the ec2 imds region
246// configuration value
247type ec2IMDSRegionProvider interface {
248	getEC2IMDSRegion(ctx context.Context) (string, bool, error)
249}
250
251// getEC2IMDSRegion searches the configs for a ec2IMDSRegionProvider and
252// returns the value if found. Returns an error if a provider fails before
253// a value is found.
254func getEC2IMDSRegion(ctx context.Context, configs configs) (region string, found bool, err error) {
255	for _, cfg := range configs {
256		if provider, ok := cfg.(ec2IMDSRegionProvider); ok {
257			region, found, err = provider.getEC2IMDSRegion(ctx)
258			if err != nil || found {
259				break
260			}
261		}
262	}
263	return
264}
265
266// credentialsProviderProvider provides access to the credentials external
267// configuration value.
268type credentialsProviderProvider interface {
269	getCredentialsProvider(ctx context.Context) (aws.CredentialsProvider, bool, error)
270}
271
272// getCredentialsProvider searches the configs for a credentialsProviderProvider
273// and returns the value if found. Returns an error if a provider fails before a
274// value is found.
275func getCredentialsProvider(ctx context.Context, configs configs) (p aws.CredentialsProvider, found bool, err error) {
276	for _, cfg := range configs {
277		if provider, ok := cfg.(credentialsProviderProvider); ok {
278			p, found, err = provider.getCredentialsProvider(ctx)
279			if err != nil || found {
280				break
281			}
282		}
283	}
284	return
285}
286
287// credentialsCacheOptionsProvider is an interface for retrieving a function for setting
288// the aws.CredentialsCacheOptions.
289type credentialsCacheOptionsProvider interface {
290	getCredentialsCacheOptions(ctx context.Context) (func(*aws.CredentialsCacheOptions), bool, error)
291}
292
293// getCredentialsCacheOptionsProvider is an interface for retrieving a function for setting
294// the aws.CredentialsCacheOptions.
295func getCredentialsCacheOptionsProvider(ctx context.Context, configs configs) (
296	f func(*aws.CredentialsCacheOptions), found bool, err error,
297) {
298	for _, config := range configs {
299		if p, ok := config.(credentialsCacheOptionsProvider); ok {
300			f, found, err = p.getCredentialsCacheOptions(ctx)
301			if err != nil || found {
302				break
303			}
304		}
305	}
306	return
307}
308
309// bearerAuthTokenProviderProvider provides access to the bearer authentication
310// token external configuration value.
311type bearerAuthTokenProviderProvider interface {
312	getBearerAuthTokenProvider(context.Context) (smithybearer.TokenProvider, bool, error)
313}
314
315// getBearerAuthTokenProvider searches the config sources for a
316// bearerAuthTokenProviderProvider and returns the value if found. Returns an
317// error if a provider fails before a value is found.
318func getBearerAuthTokenProvider(ctx context.Context, configs configs) (p smithybearer.TokenProvider, found bool, err error) {
319	for _, cfg := range configs {
320		if provider, ok := cfg.(bearerAuthTokenProviderProvider); ok {
321			p, found, err = provider.getBearerAuthTokenProvider(ctx)
322			if err != nil || found {
323				break
324			}
325		}
326	}
327	return
328}
329
330// bearerAuthTokenCacheOptionsProvider is an interface for retrieving a function for
331// setting the smithy-go auth/bearer#TokenCacheOptions.
332type bearerAuthTokenCacheOptionsProvider interface {
333	getBearerAuthTokenCacheOptions(context.Context) (func(*smithybearer.TokenCacheOptions), bool, error)
334}
335
336// getBearerAuthTokenCacheOptionsProvider is an interface for retrieving a function for
337// setting the smithy-go auth/bearer#TokenCacheOptions.
338func getBearerAuthTokenCacheOptions(ctx context.Context, configs configs) (
339	f func(*smithybearer.TokenCacheOptions), found bool, err error,
340) {
341	for _, config := range configs {
342		if p, ok := config.(bearerAuthTokenCacheOptionsProvider); ok {
343			f, found, err = p.getBearerAuthTokenCacheOptions(ctx)
344			if err != nil || found {
345				break
346			}
347		}
348	}
349	return
350}
351
352// ssoTokenProviderOptionsProvider is an interface for retrieving a function for
353// setting the SDK's credentials/ssocreds#SSOTokenProviderOptions.
354type ssoTokenProviderOptionsProvider interface {
355	getSSOTokenProviderOptions(context.Context) (func(*ssocreds.SSOTokenProviderOptions), bool, error)
356}
357
358// getSSOTokenProviderOptions is an interface for retrieving a function for
359// setting the SDK's credentials/ssocreds#SSOTokenProviderOptions.
360func getSSOTokenProviderOptions(ctx context.Context, configs configs) (
361	f func(*ssocreds.SSOTokenProviderOptions), found bool, err error,
362) {
363	for _, config := range configs {
364		if p, ok := config.(ssoTokenProviderOptionsProvider); ok {
365			f, found, err = p.getSSOTokenProviderOptions(ctx)
366			if err != nil || found {
367				break
368			}
369		}
370	}
371	return
372}
373
374// ssoTokenProviderOptionsProvider
375
376// processCredentialOptions is an interface for retrieving a function for setting
377// the processcreds.Options.
378type processCredentialOptions interface {
379	getProcessCredentialOptions(ctx context.Context) (func(*processcreds.Options), bool, error)
380}
381
382// getProcessCredentialOptions searches the slice of configs and returns the first function found
383func getProcessCredentialOptions(ctx context.Context, configs configs) (f func(*processcreds.Options), found bool, err error) {
384	for _, config := range configs {
385		if p, ok := config.(processCredentialOptions); ok {
386			f, found, err = p.getProcessCredentialOptions(ctx)
387			if err != nil || found {
388				break
389			}
390		}
391	}
392	return
393}
394
395// ec2RoleCredentialOptionsProvider is an interface for retrieving a function
396// for setting the ec2rolecreds.Provider options.
397type ec2RoleCredentialOptionsProvider interface {
398	getEC2RoleCredentialOptions(ctx context.Context) (func(*ec2rolecreds.Options), bool, error)
399}
400
401// getEC2RoleCredentialProviderOptions searches the slice of configs and returns the first function found
402func getEC2RoleCredentialProviderOptions(ctx context.Context, configs configs) (f func(*ec2rolecreds.Options), found bool, err error) {
403	for _, config := range configs {
404		if p, ok := config.(ec2RoleCredentialOptionsProvider); ok {
405			f, found, err = p.getEC2RoleCredentialOptions(ctx)
406			if err != nil || found {
407				break
408			}
409		}
410	}
411	return
412}
413
414// defaultRegionProvider is an interface for retrieving a default region if a region was not resolved from other sources
415type defaultRegionProvider interface {
416	getDefaultRegion(ctx context.Context) (string, bool, error)
417}
418
419// getDefaultRegion searches the slice of configs and returns the first fallback region found
420func getDefaultRegion(ctx context.Context, configs configs) (value string, found bool, err error) {
421	for _, config := range configs {
422		if p, ok := config.(defaultRegionProvider); ok {
423			value, found, err = p.getDefaultRegion(ctx)
424			if err != nil || found {
425				break
426			}
427		}
428	}
429	return
430}
431
432// endpointCredentialOptionsProvider is an interface for retrieving a function for setting
433// the endpointcreds.ProviderOptions.
434type endpointCredentialOptionsProvider interface {
435	getEndpointCredentialOptions(ctx context.Context) (func(*endpointcreds.Options), bool, error)
436}
437
438// getEndpointCredentialProviderOptions searches the slice of configs and returns the first function found
439func getEndpointCredentialProviderOptions(ctx context.Context, configs configs) (f func(*endpointcreds.Options), found bool, err error) {
440	for _, config := range configs {
441		if p, ok := config.(endpointCredentialOptionsProvider); ok {
442			f, found, err = p.getEndpointCredentialOptions(ctx)
443			if err != nil || found {
444				break
445			}
446		}
447	}
448	return
449}
450
451// webIdentityRoleCredentialOptionsProvider is an interface for retrieving a function for setting
452// the stscreds.WebIdentityRoleProvider.
453type webIdentityRoleCredentialOptionsProvider interface {
454	getWebIdentityRoleCredentialOptions(ctx context.Context) (func(*stscreds.WebIdentityRoleOptions), bool, error)
455}
456
457// getWebIdentityCredentialProviderOptions searches the slice of configs and returns the first function found
458func getWebIdentityCredentialProviderOptions(ctx context.Context, configs configs) (f func(*stscreds.WebIdentityRoleOptions), found bool, err error) {
459	for _, config := range configs {
460		if p, ok := config.(webIdentityRoleCredentialOptionsProvider); ok {
461			f, found, err = p.getWebIdentityRoleCredentialOptions(ctx)
462			if err != nil || found {
463				break
464			}
465		}
466	}
467	return
468}
469
470// assumeRoleCredentialOptionsProvider is an interface for retrieving a function for setting
471// the stscreds.AssumeRoleOptions.
472type assumeRoleCredentialOptionsProvider interface {
473	getAssumeRoleCredentialOptions(ctx context.Context) (func(*stscreds.AssumeRoleOptions), bool, error)
474}
475
476// getAssumeRoleCredentialProviderOptions searches the slice of configs and returns the first function found
477func getAssumeRoleCredentialProviderOptions(ctx context.Context, configs configs) (f func(*stscreds.AssumeRoleOptions), found bool, err error) {
478	for _, config := range configs {
479		if p, ok := config.(assumeRoleCredentialOptionsProvider); ok {
480			f, found, err = p.getAssumeRoleCredentialOptions(ctx)
481			if err != nil || found {
482				break
483			}
484		}
485	}
486	return
487}
488
489// HTTPClient is an HTTP client implementation
490type HTTPClient interface {
491	Do(*http.Request) (*http.Response, error)
492}
493
494// httpClientProvider is an interface for retrieving HTTPClient
495type httpClientProvider interface {
496	getHTTPClient(ctx context.Context) (HTTPClient, bool, error)
497}
498
499// getHTTPClient searches the slice of configs and returns the HTTPClient set on configs
500func getHTTPClient(ctx context.Context, configs configs) (client HTTPClient, found bool, err error) {
501	for _, config := range configs {
502		if p, ok := config.(httpClientProvider); ok {
503			client, found, err = p.getHTTPClient(ctx)
504			if err != nil || found {
505				break
506			}
507		}
508	}
509	return
510}
511
512// apiOptionsProvider is an interface for retrieving APIOptions
513type apiOptionsProvider interface {
514	getAPIOptions(ctx context.Context) ([]func(*middleware.Stack) error, bool, error)
515}
516
517// getAPIOptions searches the slice of configs and returns the APIOptions set on configs
518func getAPIOptions(ctx context.Context, configs configs) (apiOptions []func(*middleware.Stack) error, found bool, err error) {
519	for _, config := range configs {
520		if p, ok := config.(apiOptionsProvider); ok {
521			// retrieve APIOptions from configs and set it on cfg
522			apiOptions, found, err = p.getAPIOptions(ctx)
523			if err != nil || found {
524				break
525			}
526		}
527	}
528	return
529}
530
531// endpointResolverProvider is an interface for retrieving an aws.EndpointResolver from a configuration source
532type endpointResolverProvider interface {
533	getEndpointResolver(ctx context.Context) (aws.EndpointResolver, bool, error)
534}
535
536// getEndpointResolver searches the provided config sources for a EndpointResolverFunc that can be used
537// to configure the aws.Config.EndpointResolver value.
538func getEndpointResolver(ctx context.Context, configs configs) (f aws.EndpointResolver, found bool, err error) {
539	for _, c := range configs {
540		if p, ok := c.(endpointResolverProvider); ok {
541			f, found, err = p.getEndpointResolver(ctx)
542			if err != nil || found {
543				break
544			}
545		}
546	}
547	return
548}
549
550// endpointResolverWithOptionsProvider is an interface for retrieving an aws.EndpointResolverWithOptions from a configuration source
551type endpointResolverWithOptionsProvider interface {
552	getEndpointResolverWithOptions(ctx context.Context) (aws.EndpointResolverWithOptions, bool, error)
553}
554
555// getEndpointResolver searches the provided config sources for a EndpointResolverFunc that can be used
556// to configure the aws.Config.EndpointResolver value.
557func getEndpointResolverWithOptions(ctx context.Context, configs configs) (f aws.EndpointResolverWithOptions, found bool, err error) {
558	for _, c := range configs {
559		if p, ok := c.(endpointResolverWithOptionsProvider); ok {
560			f, found, err = p.getEndpointResolverWithOptions(ctx)
561			if err != nil || found {
562				break
563			}
564		}
565	}
566	return
567}
568
569// loggerProvider is an interface for retrieving a logging.Logger from a configuration source.
570type loggerProvider interface {
571	getLogger(ctx context.Context) (logging.Logger, bool, error)
572}
573
574// getLogger searches the provided config sources for a logging.Logger that can be used
575// to configure the aws.Config.Logger value.
576func getLogger(ctx context.Context, configs configs) (l logging.Logger, found bool, err error) {
577	for _, c := range configs {
578		if p, ok := c.(loggerProvider); ok {
579			l, found, err = p.getLogger(ctx)
580			if err != nil || found {
581				break
582			}
583		}
584	}
585	return
586}
587
588// clientLogModeProvider is an interface for retrieving the aws.ClientLogMode from a configuration source.
589type clientLogModeProvider interface {
590	getClientLogMode(ctx context.Context) (aws.ClientLogMode, bool, error)
591}
592
593func getClientLogMode(ctx context.Context, configs configs) (m aws.ClientLogMode, found bool, err error) {
594	for _, c := range configs {
595		if p, ok := c.(clientLogModeProvider); ok {
596			m, found, err = p.getClientLogMode(ctx)
597			if err != nil || found {
598				break
599			}
600		}
601	}
602	return
603}
604
605// retryProvider is an configuration provider for custom Retryer.
606type retryProvider interface {
607	getRetryer(ctx context.Context) (func() aws.Retryer, bool, error)
608}
609
610func getRetryer(ctx context.Context, configs configs) (v func() aws.Retryer, found bool, err error) {
611	for _, c := range configs {
612		if p, ok := c.(retryProvider); ok {
613			v, found, err = p.getRetryer(ctx)
614			if err != nil || found {
615				break
616			}
617		}
618	}
619	return
620}
621
622// logConfigurationWarningsProvider is an configuration provider for
623// retrieving a boolean indicating whether configuration issues should
624// be logged when loading from config sources
625type logConfigurationWarningsProvider interface {
626	getLogConfigurationWarnings(ctx context.Context) (bool, bool, error)
627}
628
629func getLogConfigurationWarnings(ctx context.Context, configs configs) (v bool, found bool, err error) {
630	for _, c := range configs {
631		if p, ok := c.(logConfigurationWarningsProvider); ok {
632			v, found, err = p.getLogConfigurationWarnings(ctx)
633			if err != nil || found {
634				break
635			}
636		}
637	}
638	return
639}
640
641// ssoCredentialOptionsProvider is an interface for retrieving a function for setting
642// the ssocreds.Options.
643type ssoCredentialOptionsProvider interface {
644	getSSOProviderOptions(context.Context) (func(*ssocreds.Options), bool, error)
645}
646
647func getSSOProviderOptions(ctx context.Context, configs configs) (v func(options *ssocreds.Options), found bool, err error) {
648	for _, c := range configs {
649		if p, ok := c.(ssoCredentialOptionsProvider); ok {
650			v, found, err = p.getSSOProviderOptions(ctx)
651			if err != nil || found {
652				break
653			}
654		}
655	}
656	return v, found, err
657}
658
659type defaultsModeIMDSClientProvider interface {
660	getDefaultsModeIMDSClient(context.Context) (*imds.Client, bool, error)
661}
662
663func getDefaultsModeIMDSClient(ctx context.Context, configs configs) (v *imds.Client, found bool, err error) {
664	for _, c := range configs {
665		if p, ok := c.(defaultsModeIMDSClientProvider); ok {
666			v, found, err = p.getDefaultsModeIMDSClient(ctx)
667			if err != nil || found {
668				break
669			}
670		}
671	}
672	return v, found, err
673}
674
675type defaultsModeProvider interface {
676	getDefaultsMode(context.Context) (aws.DefaultsMode, bool, error)
677}
678
679func getDefaultsMode(ctx context.Context, configs configs) (v aws.DefaultsMode, found bool, err error) {
680	for _, c := range configs {
681		if p, ok := c.(defaultsModeProvider); ok {
682			v, found, err = p.getDefaultsMode(ctx)
683			if err != nil || found {
684				break
685			}
686		}
687	}
688	return v, found, err
689}
690
691type retryMaxAttemptsProvider interface {
692	GetRetryMaxAttempts(context.Context) (int, bool, error)
693}
694
695func getRetryMaxAttempts(ctx context.Context, configs configs) (v int, found bool, err error) {
696	for _, c := range configs {
697		if p, ok := c.(retryMaxAttemptsProvider); ok {
698			v, found, err = p.GetRetryMaxAttempts(ctx)
699			if err != nil || found {
700				break
701			}
702		}
703	}
704	return v, found, err
705}
706
707type retryModeProvider interface {
708	GetRetryMode(context.Context) (aws.RetryMode, bool, error)
709}
710
711func getRetryMode(ctx context.Context, configs configs) (v aws.RetryMode, found bool, err error) {
712	for _, c := range configs {
713		if p, ok := c.(retryModeProvider); ok {
714			v, found, err = p.GetRetryMode(ctx)
715			if err != nil || found {
716				break
717			}
718		}
719	}
720	return v, found, err
721}