检查 REST 目录配置

您可以使用以下场景来检查是否为 Iceberg REST 目录正确配置了授权和访问控制,以便 Snowflake 可以与目录服务器进行交互。

使用 SYSTEM$VERIFY_CATALOG_INTEGRATION

您可以使用 SYSTEM$VERIFY_CATALOG_INTEGRATION 函数检查目录集成配置。

以下示例演示了系统函数如何捕获和报告目录集成配置不当的问题。

以下示例语句使用无效的 OAuth 客户端密钥创建 REST 目录集成(此操作运行时不会报错):

CREATE CATALOG INTEGRATION my_rest_cat_int
  CATALOG_SOURCE = ICEBERG_REST
  TABLE_FORMAT = ICEBERG
  CATALOG_NAMESPACE = 'default'
  REST_CONFIG = (
    CATALOG_URI = 'https://abc123.us-west-2.aws.myapi.com/polaris/api/catalog'
    CATALOG_NAME = 'my_catalog_name'
  )
  REST_AUTHENTICATION = (
    TYPE = OAUTH
    OAUTH_CLIENT_ID = '123AbC ...'
    OAUTH_CLIENT_SECRET = '1365910abIncorrectSecret ...'
    OAUTH_ALLOWED_SCOPES = ('all-apis', 'sql')
  )
  ENABLED = TRUE;
Copy

使用系统函数验证目录集成,预计会失败:

SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('my_rest_cat_int');
Copy

输出:

+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                                              SYSTEM$VERIFY_CATALOG_INTEGRATION('MY_REST_CAT_INT')                                                                                                               |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {                                                                                                                                                                                                                                                                               |
|  "success" : false,                                                                                                                                                                                                                                                             |                                                                                                                                                                                                                                                                    |
|   "errorCode" : "004155",                                                                                                                                                                                                                                                       |
|   "errorMessage" : "SQL Execution Error: Failed to perform OAuth client credential flow for the REST Catalog integration MY_REST_CAT_INT due to error: SQL execution error: OAuth2 Access token request failed with error 'unauthorized_client:The client is not authorized'.." |
| }                                                                                                                                                                                                                                                                               |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

检查 OAuth 的配置

按照以下步骤使用远程 REST 目录检查 OAuth 的配置。

第 1 步:检索访问令牌

使用 curl 命令从目录中检索访问令牌。下面的示例请求从 Snowflake Open Catalog 获取访问令牌:

curl -X POST https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/oauth/tokens \
    -H "Accepts: application/json" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    --data-urlencode "grant_type=client_credentials" \
    --data-urlencode "scope=PRINCIPAL_ROLE:ALL" \
    --data-urlencode "client_id=<my_client_id>" \
    --data-urlencode "client_secret=<my_client_secret>" | jq
Copy

其中:

  • https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/oauth/tokens 是检索 OAuth 令牌 (getToken (https://github.com/apache/iceberg/blob/apache-iceberg-1.6.1/open-api/rest-catalog-open-api.yaml#L132)) 的端点。

  • scope 与创建目录集成时为 OAUTH_ALLOWED_SCOPES 参数指定的值相同。对于多个范围,请使用空格作为分隔符。

  • my_client_id 与创建目录集成时为 OAUTH_CLIENT_ID 参数指定的客户端 ID 相同。

  • my_client_secret 与创建目录集成时为 OAUTH_CLIENT_SECRET 参数指定的客户端密钥相同。

返回值示例:

{
  "access_token": "xxxxxxxxxxxxxxxx",
  "token_type": "bearer",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "expires_in": 3600
}

第 2 步:验证访问令牌权限

使用在上一步中检索到的访问令牌,验证自己是否拥有访问目录服务器的权限。

您可以使用 curl 命令列出目录的配置设置:

curl -X GET "https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/config?warehouse=<warehouse>" \
    -H "Accepts: application/json" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq
Copy

其中:

  • ?warehouse=warehouse 可选择指定从目录中请求的仓库名称(如果支持)。对于 Snowflake Open Catalog,仓库名称就是目录名称。

  • ACCESS_TOKEN 是一个变量,其中包含您在上一步中检索到的 access_token

返回值示例:

{
  "defaults": {
    "default-base-location": "s3://my-bucket/polaris/"
  },
  "overrides": {
    "prefix": "my-catalog"
  }
}

第 3 步:从目录中加载表

您也可以发出 GET 请求来加载表。Snowflake 使用 loadTable (https://github.com/apache/iceberg/blob/apache-iceberg-1.6.1/open-api/rest-catalog-open-api.yaml#L616) 操作从 REST 目录中加载表数据。

curl -X GET "https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/<prefix>/namespaces/<namespace>/tables/<table>" \
    -H "Accepts: application/json" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq
Copy

其中:

  • prefix 可选择指定从上一次 getConfig 响应中获取的前缀。

  • namespace 是要检索的表的命名空间。如果命名空间是嵌套的,请使用 %1F 分隔符;例如,parentNamespace%1FchildNamespace

  • table 是表名称。

检查持有者令牌的配置

按照以下步骤在远程 REST 目录中检查使用持有者令牌的配置。

第 1 步:验证访问令牌权限

使用 curl 命令验证是否有权限访问目录服务器:

curl -X GET "https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/config?warehouse=<warehouse>" \
    -H "Accepts: application/json" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "Authorization: Bearer ${BEARER_TOKEN}" | jq
Copy

其中:

  • https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/oauth/tokens 是检索 OAuth 令牌 (getToken (https://github.com/apache/iceberg/blob/apache-iceberg-1.6.1/open-api/rest-catalog-open-api.yaml#L132)) 的端点。

  • ?warehouse=warehouse 可选择指定从目录中请求的仓库名称(如果支持)。

  • BEARER_TOKEN 是一个变量,其中包含您在上一步中检索到的 access_token

返回值示例:

{
  "defaults": {
    "default-base-location": "s3://my-bucket/polaris"
  },
  "overrides": {
    "prefix": "my-catalog"
  }
}

第 2 步:从目录中加载表

您也可以发出 GET 请求来加载表。Snowflake 使用 loadTable (https://github.com/apache/iceberg/blob/apache-iceberg-1.6.1/open-api/rest-catalog-open-api.yaml#L616) 操作从 REST 目录中加载表数据。

curl -X GET "https://xx123xx.us-west-2.aws.snowflakecomputing.cn/polaris/api/catalog/v1/<prefix>/namespaces/<namespace>/tables/<table>" \
    -H "Accepts: application/json" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "Authorization: Bearer ${BEARER_TOKEN}" | jq
Copy

其中:

  • prefix 可选择指定从上一次 getConfig 响应中获取的前缀。

  • namespace 是要检索的表的命名空间。如果命名空间是嵌套的,请使用 %1F 分隔符;例如,parentNamespace%1FchildNamespace

  • table 是表名称。

检查 SigV4 的配置

按照以下步骤通过 AWS 检查 SigV4 的配置。

第 1 步:将用户添加到 IAM 角色信任关系中

当您为 SigV4 创建 REST 目录集成时,Snowflake 会为 Snowflake 账户配置 AWS IAM 用户。您 将该 Snowflake IAM 用户添加到 :ref:`IAM 角色 的信任关系 <label-tables_iceberg_rest_catalog_integration_trust_relationship_sigv4>` 中,该角色有权访问 API Gateway 资源。

要测试您的配置, 可以在将 AWS 用户添加到角色的信任策略文档后,以 AWS 账户中的用户身份担任该角色。要检索当前 IAM 用户 ARN,请使用 AWS 命令行界面 (CLI) (https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 的 sts get-caller-identity (https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/get-caller-identity.html) 命令:

aws sts get-caller-identity
Copy

输出示例:

{
  "UserId": "ABCDEFG1XXXXXXXXXXX",
  "Account": "123456789XXX",
  "Arn": "arn:aws:iam::123456789XXX:user/managed/my_user"
}

更新后的信任策略文档应包括 Snowflake 用户 ARN 和用户 ARN,具体如下:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "<snowflake_iam_user_arn>",
          "<my_iam_user_arn>"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "my_external_id"
        }
      }
    }
  ]
}
Copy

有关完整说明,请参阅 AWS IAM 文档中的 更新角色信任策略 (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-trust-policy.html)。

第 2 步:假设 IAM 角色以获取临时凭证

要获取 AWS 的临时安全凭证,请使用 AWS CLI 的 sts assume-role (https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/assume-role.html) 命令。

aws sts assume-role \
  --role-arn <my_role_arn> \
  --role-session-name <session_name>
Copy

其中:

  • my_role_arn 是您为 Snowflake 配置的 IAM 角色的 Amazon 资源名称 (ARN)。

  • session_name 是您为假设角色会话选择的字符串标识符;例如,my_rest_session

输出示例:

{
  "Credentials": {
      "AccessKeyId": "XXXXXXXXXXXXXXXXXXXXX",
      "SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXX",
      "SessionToken": "XXXXXXXXXXXXXXXXXXXXX",
      "Expiration": "2024-10-09T08:13:15+00:00"
  },
  "AssumedRoleUser": {
      "AssumedRoleId": "{AccessKeyId}:my_rest_catalog_session",
      "Arn": "arn:aws:sts::123456789XXX:assumed-role/my_catalog_role/my_rest_catalog_session"
  }
}

备注

如果 assume-role 命令失败,说明当前的 AWS 用户没有作为允许的主体包含在角色的信任策略中。

同样,如果信任策略中不包含 Snowflake IAM 用户 ARN,Snowflake 将无法连接到 API Gateway 资源。有关更多信息,请参阅 配置 IAM 中的信任关系

第 3 步:确认 IAM 角色是否拥有正确的权限

使用在上一步中检索到的临时凭证,验证 IAM 角色是否拥有调用 API Gateway APIs 的权限。

您可以使用 curl 命令列出目录的配置设置:

curl -v -X GET  "https://123xxxxxxx.execute-api.us-west-2.amazonaws.com/test_v2/v1/config?warehouse=<warehouse>" \
  --user "$AWS_ACCESS_KEY_ID":"$AWS_SECRET_ACCESS_KEY" \
  --aws-sigv4 "aws:amz:us-west-2:execute-api" \
  -H "x-amz-security-token: $AWS_SESSION_TOKEN"
Copy

其中:

  • 123xxxxxxx.execute-api.us-west-2.amazonaws.com 是 API Gateway 主机名。

  • test_v2 是 API 部署到的暂存区的名称。

  • v1/config 根据 Iceberg 目录 OpenAPI 定义指定 getConfig (https://github.com/apache/iceberg/blob/apache-iceberg-1.6.1/open-api/rest-catalog-open-api.yaml#L65) 操作。

  • ?warehouse=warehouse 可选择指定从目录中请求的仓库名称(如果支持)。

  • $AWS_ACCESS_KEY_ID 是一个变量,其中包含使用 sts assume-role 命令检索的 AccessKeyId

  • $AWS_SECRET_ACCESS_KEY 是一个变量,其中包含使用 sts assume-role 命令检索的 SecretAccessKey

  • aws:amz:us-west-2:execute-api 是 SigV4 协议的签名名称。对于 AWS Glue,则改用 aws:amz:us-west-2:glue

  • $AWS_SESSION_TOKEN 是一个变量,其中包含使用 sts assume-role 命令检索的 SessionToken

返回值示例:

{
  "defaults": {},
  "overrides": {
    "prefix": "my-catalog"
  }
}

您也可以发出 GET 请求来加载表。Snowflake 使用 loadTable (https://github.com/apache/iceberg/blob/apache-iceberg-1.6.1/open-api/rest-catalog-open-api.yaml#L616) 操作从 REST 目录中加载表数据。

curl -v -X GET "https://123xxxxxxx.execute-api.us-west-2.amazonaws.com/test_v2/v1/<prefix>/namespaces/<namespace>/tables/<table>" \
    --user "$AWS_ACCESS_KEY_ID":"$AWS_SECRET_ACCESS_KEY" \
    --aws-sigv4 "aws:amz:us-west-2:execute-api" \
    -H "x-amz-security-token: $AWS_SESSION_TOKEN"
Copy

其中:

  • prefix 可选择指定从上一次 getConfig 响应中获取的前缀。

  • namespace 是要检索的表的命名空间。如果命名空间是嵌套的,请使用 %1F 分隔符;例如,parentNamespace%1FchildNamespace

  • table 是表名称。

专用 API

对于专用 API,可以在相同的 curl 命令中指定 VPC 端点和专用 Amazon API Gateway 主机名。

例如:

curl -v -X GET  "https://vpce-xxxxxxxxxxxxxxxxxxxxxxxxxx.execute-api.us-west-2.vpce.amazonaws.com/test_v2/v1/config?warehouse=<warehouse>" \
  --user "$AWS_ACCESS_KEY_ID":"$AWS_SECRET_ACCESS_KEY" \
  --aws-sigv4 "aws:amz:us-west-2:execute-api" \
  -H "x-amz-security-token: $AWS_SESSION_TOKEN"
  -H "Host: abc1defgh2.execute-api.us-west-2.amazonaws.com"
Copy

其中:

  • https://vpce-xxxxxxxxxxxxxxxxxxxxxxxxxx.execute-api.us-west-2.vpce.amazonaws.com/... 是 VPC 端点的主机名。

  • abc1defgh2.execute-api.us-west-2.amazonaws.com is the hostname of your private API in Amazon API Gateway.

语言: 中文