smithy4s icon indicating copy to clipboard operation
smithy4s copied to clipboard

AWS: Account API ListRegions not working (unknown host)

Open kubukoz opened this issue 1 year ago • 3 comments

package smithy4sdemo

import cats.effect.IO
import cats.effect.IOApp
import com.amazonaws.account.Account
import org.http4s.ember.client.EmberClientBuilder
import smithy4s.aws.AwsClient
import smithy4s.aws.AwsEnvironment
import smithy4s.aws.kernel.AwsRegion

object Main extends IOApp.Simple {

  def run: IO[Unit] = EmberClientBuilder.default[IO].build.use { c =>
    AwsEnvironment.default(c, AwsRegion.US_EAST_1).use { env =>
      AwsClient(Account, env).use { api =>
        api.listRegions().debug().void
      }
    }
  }

}

Version: 0.18.19

Build:

val root = project
  .in(file("."))
  .settings(
    scalaVersion := "3.4.2",
    libraryDependencies ++= Seq(
      "com.disneystreaming.smithy4s" %% "smithy4s-aws-http4s" % smithy4sVersion.value,
      "org.http4s" %% "http4s-ember-server" % "0.23.27",
      "org.http4s" %% "http4s-ember-client" % "0.23.27",
    ),
    fork := true,
    smithy4sAwsSpecs += AWS.account,
  )
  .enablePlugins(Smithy4sCodegenPlugin)

Exception:

[info] DEBUG: Errored: java.net.UnknownHostException: ListRegions.us-east-1.amazonaws.com: nodename nor servname provided, or not known
[error] java.net.UnknownHostException: ListRegions.us-east-1.amazonaws.com: nodename nor servname provided, or not known
[error]         at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
[error]         at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:934)
[error]         at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1543)
[error]         at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:852)
[error]         at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1533)
[error]         at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1385)
[error]         at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1306)
[error]         at java.base/java.net.InetAddress.getByName(InetAddress.java:1256)
[error]         at com.comcast.ip4s.DnsCompanionPlatform.com$comcast$ip4s$DnsCompanionPlatform$$anon$1$$_$resolve$$anonfun$1(DnsPlatform.scala:31)
[error]         at map @ com.comcast.ip4s.SocketAddress.resolve(SocketAddress.scala:33)
[error]         at flatMap @ fs2.io.net.SocketGroupCompanionPlatform$AsyncSocketGroup.connect$1(SocketGroupPlatform.scala:77)
[error]         at delay @ fs2.io.net.SocketGroupCompanionPlatform$AsyncSocketGroup.setup$1$$anonfun$3(SocketGroupPlatform.scala:58)
[error]         at onError$extension @ org.typelevel.keypool.KeyPool$Builder.keepRunning$1(KeyPool.scala:371)
[error]         at delay @ fs2.io.net.SocketGroupCompanionPlatform$AsyncSocketGroup.setup$1(SocketGroupPlatform.scala:55)
[error]         at main$ @ smithy4sdemo.Main$.main(Main.scala:11)
[error]         at main$ @ smithy4sdemo.Main$.main(Main.scala:11)
[error]         at map @ org.http4s.ember.client.internal.ClientHelpers$.getAddress$$anonfun$2(ClientHelpers.scala:245)
[error]         at flatMap @ org.http4s.ember.client.internal.ClientHelpers$.getAddress(ClientHelpers.scala:245)

kubukoz avatar May 19 '24 21:05 kubukoz

Got another one, with aws's Location service (needs #1592, #1594 to compile):

// sdk.listTrackers().debug().void
[E] java.net.UnknownHostException: cp.tracking.ListTrackers.us-east-1.amazonaws.com: nodename nor servname provided, or not known

A wild guess and a passing ping tell me that it should be cp.tracking.geo.us-east-1.amazonaws.com (geo is the arnNamespace for the location service, cp.tracking. is the endpoint prefix of the ListTrackers operation).

With the Account api, it would be arnNamespace: account and no prefix, so: account.us-east-1.amazonaws.com (which pings successfully).

kubukoz avatar Sep 27 '24 00:09 kubukoz

Applying a middleware as a workaround to use the correct host wasn't enough: I still get a Forbidden response.

The things that are different at the moment when we compare to the CLI:

  • X-Amz-Target doesn't get sent in the CLI and isn't part of the signed headers list, I don't know if this is an issue
  • the host header matches the URI host, so they'll probably be fixed together
  • the signature is different, I assume this is because of the above two
  • the credential string in the authorization header is different: we send Credential=<redacted>/20240927/us-east-1/locationservice/aws4_request, CLI sends Credential=<redacted>/20240927/us-east-1/geo/aws4_request.

On a positive note, the security token is identical.

kubukoz avatar Sep 27 '24 00:09 kubukoz

This seems to be resolvable by updating baseRequest in AwsClient.scala, however we then bump into #1568.

I made an early draft of a fix for both issues in #1596.

kubukoz avatar Sep 27 '24 01:09 kubukoz