为GCP PubSub SubscriberClient使用python api的ImpersonatedCredent



我试图使用python pubsub API使用ImpersontatedCredentials(模拟服务帐户)创建SubscriberClient,然后使用该客户端创建一些订阅。我试图尝试在本地运行此代码(尽管最终它将被部署为云功能)

这样做,我得到这个错误:

过滤器:"属性。Provider_id = "integration_test_create_delete_provider_id_123";, metadata=[('x-goog-request-params', 'name=projects/my-project/subscriptions/integration_test_create_delete_provider_id_123'), ('x-goog-api-client', 'gl-python/3.8.6 grpc/1.39.0 gax/1.31.1 gccl/2.7.0')]),最后一个例外:503从插件获取元数据失败,错误:('无法获取冒充凭证:没有访问令牌或无效过期响应。', '{n "error"; {n "code": 400,n "message": "请求包含无效参数",n "status": "INVALID_ARGUMENT"n}n}n')

我创建模拟凭证的代码如下所示:
from google.auth import impersonated_credentials
from google.cloud import pubsub_v1
target_scopes = [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/pubsub",
]
target_principal = ("target-svc-account@my-project.iam.gserviceaccount.com",)
def _get_impersonated_pubsub_client():
return pubsub_v1.SubscriberClient(credentials=_get_impersonated_creds())

def _get_impersonated_creds():
default_creds, _ = google.auth.default()
impersonated_creds = impersonated_credentials.Credentials(
source_credentials=default_creds,
target_principal=target_principal,
target_scopes=target_scopes,
)
return impersonated_creds

从那里,我在调用_get_impersonated_pubsub_client()获得的客户机上调用create_subscription(request=my_request),大约一分钟后,我看到上述错误。

我的请求对象是这样的:

{
"name": "projects/my-project/subscriptions/integration_test_create_delete_provider_id_123",
"topic": "projects/my-project/topics/my-topic-dev-us-west1",
}

如果我在没有模拟或在SubscriberClient构造函数中指定凭据的情况下进行相同的调用,则一切正常。

我的第一个想法是这是一个权限错误,但我仔细检查了我的源帐户具有ServiceAccountTokenCreator角色。

另外,我试着用GCloud CLI(包括模拟)运行一个等效的命令,像这样:

gcloud pubsub subscriptions create my_subscription_name --topic=projects/my-project/topics/my-topic-dev-us-west1 --impersonate-service-account target-svc-account@my-project.iam.gserviceaccount.com

这完全如预期的那样工作——这使我相信GCP中的权限设置是正确的。

是否SubscriberClient不能与ImpersonatedCredentials一起工作,或者我可以做一些强制操作来使验证工作?

我还确保运行gcloud config unset auth/impersonate_service_accountgcloud auth application-default login,以确保我的本地凭据处于良好状态。

相关的依赖关系:

google-api-core[grpc]==1.31.1; platform_python_implementation != 'PyPy'
google-api-python-client==2.15.0; python_version >= '3.6'
google-auth-httplib2==0.1.0
google-auth==1.34.0
google-cloud-core==2.0.0b1; python_version >= '3.6'
google-cloud-firestore==2.2.0; platform_python_implementation != 'PyPy'
google-cloud-pubsub==2.7.0
google-cloud-storage==1.41.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'
google-crc32c==1.1.2; python_version >= '3.6'
google-resumable-media==2.0.0b1; python_version >= '3.6'
googleapis-common-protos[grpc]==1.53.0; python_version >= '3.6'
grpc-google-iam-v1==0.12.3
grpcio==1.39.0
httplib2==0.19.1

你的Python代码看起来是正确的。

完成以下步骤:

  1. 列出已启用的服务:

gcloud services list——enabled

  1. 验证iamcredentials.googleapis.com启用。启用:

gcloud services enable iamcredentials.googleapis.com

  1. 验证cloudresourcemanager.googleapis.com启用。启用:

gcloud services enable cloudresourcemanager.googleapis.com

  1. 检查Compute Engine默认服务帐户是否具有角色roles/iam.serviceAccountTokenCreator或更好。

需要的权限有:

  • iam.serviceAccounts.getAccessToken

  • iam.serviceAccounts.getOpenIdToken(获取身份令牌需要此权限)。

    gcloud projects add-iam-policy-binding [PROECT_ID]
    ——member "服务帐户:[GCE_DEFAULT_SA_FULL_EMAIL]">
    ——role "roles/iam.serviceAccountTokenCreator">

  1. 检查Compute Engine默认服务帐户是否存在角色roles/serviceusage.serviceUsageConsumer或更好。

    gcloud projects add-iam-policy-binding [PROECT_ID]
    ——member "服务帐户:[GCE_DEFAULT_SA_FULL_EMAIL]">
    ——role "roles/serviceusage.serviceUsageConsumer">

如果没有启用/授予上述任何一个,令牌发布将失败。

注意:如果您只希望Compute Engine服务帐户能够模拟一个服务帐户,请更改步骤4以在服务帐户而不是项目上授予角色:

gcloud iam service-accounts add-iam-policy-binding [SA_FULL_EMAIL] 
--member serviceAccount:[GCE_DEFAULT_SA_FULL_EMAIL] 
--role roles/iam.serviceAccountTokenCreator

相关内容

  • 没有找到相关文章

最新更新