检查 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;
使用系统函数验证目录集成,预计会失败:
SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('my_rest_cat_int');
输出:
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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
其中:
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
其中:
?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
其中:
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
其中:
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
其中:
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
输出示例:
{
"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"
}
}
}
]
}
有关完整说明,请参阅 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>
其中:
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"
其中:
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"
其中:
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"
其中:
https://vpce-xxxxxxxxxxxxxxxxxxxxxxxxxx.execute-api.us-west-2.vpce.amazonaws.com/...是 VPC 端点的主机名。abc1defgh2.execute-api.us-west-2.amazonaws.comis the hostname of your private API in Amazon API Gateway.