endpoints.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. // Code generated by smithy-go-codegen DO NOT EDIT.
  2. package ssooidc
  3. import (
  4. "context"
  5. "errors"
  6. "fmt"
  7. "github.com/aws/aws-sdk-go-v2/aws"
  8. awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
  9. internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources"
  10. "github.com/aws/aws-sdk-go-v2/internal/endpoints"
  11. "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn"
  12. internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints"
  13. smithyauth "github.com/aws/smithy-go/auth"
  14. smithyendpoints "github.com/aws/smithy-go/endpoints"
  15. "github.com/aws/smithy-go/middleware"
  16. "github.com/aws/smithy-go/ptr"
  17. "github.com/aws/smithy-go/tracing"
  18. smithyhttp "github.com/aws/smithy-go/transport/http"
  19. "net/http"
  20. "net/url"
  21. "os"
  22. "strings"
  23. )
  24. // EndpointResolverOptions is the service endpoint resolver options
  25. type EndpointResolverOptions = internalendpoints.Options
  26. // EndpointResolver interface for resolving service endpoints.
  27. type EndpointResolver interface {
  28. ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
  29. }
  30. var _ EndpointResolver = &internalendpoints.Resolver{}
  31. // NewDefaultEndpointResolver constructs a new service endpoint resolver
  32. func NewDefaultEndpointResolver() *internalendpoints.Resolver {
  33. return internalendpoints.New()
  34. }
  35. // EndpointResolverFunc is a helper utility that wraps a function so it satisfies
  36. // the EndpointResolver interface. This is useful when you want to add additional
  37. // endpoint resolving logic, or stub out specific endpoints with custom values.
  38. type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error)
  39. func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
  40. return fn(region, options)
  41. }
  42. // EndpointResolverFromURL returns an EndpointResolver configured using the
  43. // provided endpoint url. By default, the resolved endpoint resolver uses the
  44. // client region as signing region, and the endpoint source is set to
  45. // EndpointSourceCustom.You can provide functional options to configure endpoint
  46. // values for the resolved endpoint.
  47. func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver {
  48. e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom}
  49. for _, fn := range optFns {
  50. fn(&e)
  51. }
  52. return EndpointResolverFunc(
  53. func(region string, options EndpointResolverOptions) (aws.Endpoint, error) {
  54. if len(e.SigningRegion) == 0 {
  55. e.SigningRegion = region
  56. }
  57. return e, nil
  58. },
  59. )
  60. }
  61. type ResolveEndpoint struct {
  62. Resolver EndpointResolver
  63. Options EndpointResolverOptions
  64. }
  65. func (*ResolveEndpoint) ID() string {
  66. return "ResolveEndpoint"
  67. }
  68. func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
  69. out middleware.SerializeOutput, metadata middleware.Metadata, err error,
  70. ) {
  71. if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
  72. return next.HandleSerialize(ctx, in)
  73. }
  74. req, ok := in.Request.(*smithyhttp.Request)
  75. if !ok {
  76. return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
  77. }
  78. if m.Resolver == nil {
  79. return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
  80. }
  81. eo := m.Options
  82. eo.Logger = middleware.GetLogger(ctx)
  83. var endpoint aws.Endpoint
  84. endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo)
  85. if err != nil {
  86. nf := (&aws.EndpointNotFoundError{})
  87. if errors.As(err, &nf) {
  88. ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false)
  89. return next.HandleSerialize(ctx, in)
  90. }
  91. return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
  92. }
  93. req.URL, err = url.Parse(endpoint.URL)
  94. if err != nil {
  95. return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err)
  96. }
  97. if len(awsmiddleware.GetSigningName(ctx)) == 0 {
  98. signingName := endpoint.SigningName
  99. if len(signingName) == 0 {
  100. signingName = "sso-oauth"
  101. }
  102. ctx = awsmiddleware.SetSigningName(ctx, signingName)
  103. }
  104. ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source)
  105. ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable)
  106. ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion)
  107. ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID)
  108. return next.HandleSerialize(ctx, in)
  109. }
  110. func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error {
  111. return stack.Serialize.Insert(&ResolveEndpoint{
  112. Resolver: o.EndpointResolver,
  113. Options: o.EndpointOptions,
  114. }, "OperationSerializer", middleware.Before)
  115. }
  116. func removeResolveEndpointMiddleware(stack *middleware.Stack) error {
  117. _, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID())
  118. return err
  119. }
  120. type wrappedEndpointResolver struct {
  121. awsResolver aws.EndpointResolverWithOptions
  122. }
  123. func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
  124. return w.awsResolver.ResolveEndpoint(ServiceID, region, options)
  125. }
  126. type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error)
  127. func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) {
  128. return a(service, region)
  129. }
  130. var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil)
  131. // withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver.
  132. // If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error,
  133. // and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked
  134. // via its middleware.
  135. //
  136. // If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated.
  137. func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver {
  138. var resolver aws.EndpointResolverWithOptions
  139. if awsResolverWithOptions != nil {
  140. resolver = awsResolverWithOptions
  141. } else if awsResolver != nil {
  142. resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint)
  143. }
  144. return &wrappedEndpointResolver{
  145. awsResolver: resolver,
  146. }
  147. }
  148. func finalizeClientEndpointResolverOptions(options *Options) {
  149. options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage()
  150. if len(options.EndpointOptions.ResolvedRegion) == 0 {
  151. const fipsInfix = "-fips-"
  152. const fipsPrefix = "fips-"
  153. const fipsSuffix = "-fips"
  154. if strings.Contains(options.Region, fipsInfix) ||
  155. strings.Contains(options.Region, fipsPrefix) ||
  156. strings.Contains(options.Region, fipsSuffix) {
  157. options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
  158. options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "")
  159. options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
  160. }
  161. }
  162. }
  163. func resolveEndpointResolverV2(options *Options) {
  164. if options.EndpointResolverV2 == nil {
  165. options.EndpointResolverV2 = NewDefaultEndpointResolverV2()
  166. }
  167. }
  168. func resolveBaseEndpoint(cfg aws.Config, o *Options) {
  169. if cfg.BaseEndpoint != nil {
  170. o.BaseEndpoint = cfg.BaseEndpoint
  171. }
  172. _, g := os.LookupEnv("AWS_ENDPOINT_URL")
  173. _, s := os.LookupEnv("AWS_ENDPOINT_URL_SSO_OIDC")
  174. if g && !s {
  175. return
  176. }
  177. value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "SSO OIDC", cfg.ConfigSources)
  178. if found && err == nil {
  179. o.BaseEndpoint = &value
  180. }
  181. }
  182. func bindRegion(region string) *string {
  183. if region == "" {
  184. return nil
  185. }
  186. return aws.String(endpoints.MapFIPSRegion(region))
  187. }
  188. // EndpointParameters provides the parameters that influence how endpoints are
  189. // resolved.
  190. type EndpointParameters struct {
  191. // The AWS region used to dispatch the request.
  192. //
  193. // Parameter is
  194. // required.
  195. //
  196. // AWS::Region
  197. Region *string
  198. // When true, use the dual-stack endpoint. If the configured endpoint does not
  199. // support dual-stack, dispatching the request MAY return an error.
  200. //
  201. // Defaults to
  202. // false if no value is provided.
  203. //
  204. // AWS::UseDualStack
  205. UseDualStack *bool
  206. // When true, send this request to the FIPS-compliant regional endpoint. If the
  207. // configured endpoint does not have a FIPS compliant endpoint, dispatching the
  208. // request will return an error.
  209. //
  210. // Defaults to false if no value is
  211. // provided.
  212. //
  213. // AWS::UseFIPS
  214. UseFIPS *bool
  215. // Override the endpoint used to send this request
  216. //
  217. // Parameter is
  218. // required.
  219. //
  220. // SDK::Endpoint
  221. Endpoint *string
  222. }
  223. // ValidateRequired validates required parameters are set.
  224. func (p EndpointParameters) ValidateRequired() error {
  225. if p.UseDualStack == nil {
  226. return fmt.Errorf("parameter UseDualStack is required")
  227. }
  228. if p.UseFIPS == nil {
  229. return fmt.Errorf("parameter UseFIPS is required")
  230. }
  231. return nil
  232. }
  233. // WithDefaults returns a shallow copy of EndpointParameterswith default values
  234. // applied to members where applicable.
  235. func (p EndpointParameters) WithDefaults() EndpointParameters {
  236. if p.UseDualStack == nil {
  237. p.UseDualStack = ptr.Bool(false)
  238. }
  239. if p.UseFIPS == nil {
  240. p.UseFIPS = ptr.Bool(false)
  241. }
  242. return p
  243. }
  244. type stringSlice []string
  245. func (s stringSlice) Get(i int) *string {
  246. if i < 0 || i >= len(s) {
  247. return nil
  248. }
  249. v := s[i]
  250. return &v
  251. }
  252. // EndpointResolverV2 provides the interface for resolving service endpoints.
  253. type EndpointResolverV2 interface {
  254. // ResolveEndpoint attempts to resolve the endpoint with the provided options,
  255. // returning the endpoint if found. Otherwise an error is returned.
  256. ResolveEndpoint(ctx context.Context, params EndpointParameters) (
  257. smithyendpoints.Endpoint, error,
  258. )
  259. }
  260. // resolver provides the implementation for resolving endpoints.
  261. type resolver struct{}
  262. func NewDefaultEndpointResolverV2() EndpointResolverV2 {
  263. return &resolver{}
  264. }
  265. // ResolveEndpoint attempts to resolve the endpoint with the provided options,
  266. // returning the endpoint if found. Otherwise an error is returned.
  267. func (r *resolver) ResolveEndpoint(
  268. ctx context.Context, params EndpointParameters,
  269. ) (
  270. endpoint smithyendpoints.Endpoint, err error,
  271. ) {
  272. params = params.WithDefaults()
  273. if err = params.ValidateRequired(); err != nil {
  274. return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err)
  275. }
  276. _UseDualStack := *params.UseDualStack
  277. _ = _UseDualStack
  278. _UseFIPS := *params.UseFIPS
  279. _ = _UseFIPS
  280. if exprVal := params.Endpoint; exprVal != nil {
  281. _Endpoint := *exprVal
  282. _ = _Endpoint
  283. if _UseFIPS == true {
  284. return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported")
  285. }
  286. if _UseDualStack == true {
  287. return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported")
  288. }
  289. uriString := _Endpoint
  290. uri, err := url.Parse(uriString)
  291. if err != nil {
  292. return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
  293. }
  294. return smithyendpoints.Endpoint{
  295. URI: *uri,
  296. Headers: http.Header{},
  297. }, nil
  298. }
  299. if exprVal := params.Region; exprVal != nil {
  300. _Region := *exprVal
  301. _ = _Region
  302. if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil {
  303. _PartitionResult := *exprVal
  304. _ = _PartitionResult
  305. if _UseFIPS == true {
  306. if _UseDualStack == true {
  307. if true == _PartitionResult.SupportsFIPS {
  308. if true == _PartitionResult.SupportsDualStack {
  309. uriString := func() string {
  310. var out strings.Builder
  311. out.WriteString("https://oidc-fips.")
  312. out.WriteString(_Region)
  313. out.WriteString(".")
  314. out.WriteString(_PartitionResult.DualStackDnsSuffix)
  315. return out.String()
  316. }()
  317. uri, err := url.Parse(uriString)
  318. if err != nil {
  319. return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
  320. }
  321. return smithyendpoints.Endpoint{
  322. URI: *uri,
  323. Headers: http.Header{},
  324. }, nil
  325. }
  326. }
  327. return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both")
  328. }
  329. }
  330. if _UseFIPS == true {
  331. if _PartitionResult.SupportsFIPS == true {
  332. if _PartitionResult.Name == "aws-us-gov" {
  333. uriString := func() string {
  334. var out strings.Builder
  335. out.WriteString("https://oidc.")
  336. out.WriteString(_Region)
  337. out.WriteString(".amazonaws.com")
  338. return out.String()
  339. }()
  340. uri, err := url.Parse(uriString)
  341. if err != nil {
  342. return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
  343. }
  344. return smithyendpoints.Endpoint{
  345. URI: *uri,
  346. Headers: http.Header{},
  347. }, nil
  348. }
  349. uriString := func() string {
  350. var out strings.Builder
  351. out.WriteString("https://oidc-fips.")
  352. out.WriteString(_Region)
  353. out.WriteString(".")
  354. out.WriteString(_PartitionResult.DnsSuffix)
  355. return out.String()
  356. }()
  357. uri, err := url.Parse(uriString)
  358. if err != nil {
  359. return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
  360. }
  361. return smithyendpoints.Endpoint{
  362. URI: *uri,
  363. Headers: http.Header{},
  364. }, nil
  365. }
  366. return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS")
  367. }
  368. if _UseDualStack == true {
  369. if true == _PartitionResult.SupportsDualStack {
  370. uriString := func() string {
  371. var out strings.Builder
  372. out.WriteString("https://oidc.")
  373. out.WriteString(_Region)
  374. out.WriteString(".")
  375. out.WriteString(_PartitionResult.DualStackDnsSuffix)
  376. return out.String()
  377. }()
  378. uri, err := url.Parse(uriString)
  379. if err != nil {
  380. return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
  381. }
  382. return smithyendpoints.Endpoint{
  383. URI: *uri,
  384. Headers: http.Header{},
  385. }, nil
  386. }
  387. return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack")
  388. }
  389. uriString := func() string {
  390. var out strings.Builder
  391. out.WriteString("https://oidc.")
  392. out.WriteString(_Region)
  393. out.WriteString(".")
  394. out.WriteString(_PartitionResult.DnsSuffix)
  395. return out.String()
  396. }()
  397. uri, err := url.Parse(uriString)
  398. if err != nil {
  399. return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
  400. }
  401. return smithyendpoints.Endpoint{
  402. URI: *uri,
  403. Headers: http.Header{},
  404. }, nil
  405. }
  406. return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.")
  407. }
  408. return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region")
  409. }
  410. type endpointParamsBinder interface {
  411. bindEndpointParams(*EndpointParameters)
  412. }
  413. func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters {
  414. params := &EndpointParameters{}
  415. params.Region = bindRegion(options.Region)
  416. params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled)
  417. params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled)
  418. params.Endpoint = options.BaseEndpoint
  419. if b, ok := input.(endpointParamsBinder); ok {
  420. b.bindEndpointParams(params)
  421. }
  422. return params
  423. }
  424. type resolveEndpointV2Middleware struct {
  425. options Options
  426. }
  427. func (*resolveEndpointV2Middleware) ID() string {
  428. return "ResolveEndpointV2"
  429. }
  430. func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
  431. out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
  432. ) {
  433. _, span := tracing.StartSpan(ctx, "ResolveEndpoint")
  434. defer span.End()
  435. if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
  436. return next.HandleFinalize(ctx, in)
  437. }
  438. req, ok := in.Request.(*smithyhttp.Request)
  439. if !ok {
  440. return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
  441. }
  442. if m.options.EndpointResolverV2 == nil {
  443. return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
  444. }
  445. params := bindEndpointParams(ctx, getOperationInput(ctx), m.options)
  446. endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration",
  447. func() (smithyendpoints.Endpoint, error) {
  448. return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
  449. })
  450. if err != nil {
  451. return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
  452. }
  453. span.SetProperty("client.call.resolved_endpoint", endpt.URI.String())
  454. if endpt.URI.RawPath == "" && req.URL.RawPath != "" {
  455. endpt.URI.RawPath = endpt.URI.Path
  456. }
  457. req.URL.Scheme = endpt.URI.Scheme
  458. req.URL.Host = endpt.URI.Host
  459. req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path)
  460. req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath)
  461. for k := range endpt.Headers {
  462. req.Header.Set(k, endpt.Headers.Get(k))
  463. }
  464. rscheme := getResolvedAuthScheme(ctx)
  465. if rscheme == nil {
  466. return out, metadata, fmt.Errorf("no resolved auth scheme")
  467. }
  468. opts, _ := smithyauth.GetAuthOptions(&endpt.Properties)
  469. for _, o := range opts {
  470. rscheme.SignerProperties.SetAll(&o.SignerProperties)
  471. }
  472. span.End()
  473. return next.HandleFinalize(ctx, in)
  474. }