Python 3.x 谷歌云中的SecretManagerServiceClient通过服务帐户运行和验证
我可以创建一个SecretManagerService客户端,而无需在Google Cloud Shell中成功使用密钥文件:Python 3.x 谷歌云中的SecretManagerServiceClient通过服务帐户运行和验证,python-3.x,google-cloud-platform,google-cloud-run,google-secret-manager,Python 3.x,Google Cloud Platform,Google Cloud Run,Google Secret Manager,我可以创建一个SecretManagerService客户端,而无需在Google Cloud Shell中成功使用密钥文件: from google.cloud import secretmanager from google.oauth2 import service_account from google.auth.exceptions import DefaultCredentialsError import logging import sys import os def list
from google.cloud import secretmanager
from google.oauth2 import service_account
from google.auth.exceptions import DefaultCredentialsError
import logging
import sys
import os
def list_secrets(client, project_id):
"""
Retrieve all secrets associated with a project
:param project_id: the alpha-numeric name of the project
:return: a generator of Secrets
"""
try:
secret_list = client.list_secrets(request={"parent": "projects/{}".format(project_id)})
except Exception as e:
sys.exit("Did not successfully retrieve secret list.")
return secret_list
def set_env_secrets(client, secret_ids, label=None):
"""
Sets secrets retrieved from Google Secret Manager in the runtime environment
of the Python process
:param secret_ids: a generator of Secrets
:param label: Secrets with this label will be set in the environment
"""
for s in secret_ids:
# we only want secrets with matching labels (or all of them if label wasn't specified)
if not label or label in s.labels:
version = client.access_secret_version(request={'name': '{}/versions/latest'.format(s.name)})
payload_str = version.payload.data.decode("UTF-8")
os.environ[s.name.split('/')[-1]] = payload_str
if __name__ == "__main__":
client = secretmanager.SecretManagerServiceClient()
secrets = list_secrets(client, "myprojectid-123456")
set_env_secrets(client, secrets)
print(os.getenv("DATA_DB_HOST"))
然而,当我在Google Cloud Run中使用类似的代码作为容器入口点的基础时,尝试使用默认服务帐户的凭据检索客户机失败
File "entry_point.py", line 27, in get_client
client = secretmanager.SecretManagerServiceClient()
File "/usr/local/lib/python3.6/site-packages/google/cloud/secretmanager_v1/services/secret_manager_service/client.py", line 274, in __init__
client_info=client_info,
File "/usr/local/lib/python3.6/site-packages/google/cloud/secretmanager_v1/services/secret_manager_service/transports/grpc.py", line 162, in __init__
scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
File "/usr/local/lib/python3.6/site-packages/google/auth/_default.py", line 340, in default
credentials, project_id = checker()
File "/usr/local/lib/python3.6/site-packages/google/auth/_default.py", line 186, in _get_explicit_environ_credentials
os.environ[environment_vars.CREDENTIALS]
File "/usr/local/lib/python3.6/site-packages/google/auth/_default.py", line 97, in load_credentials_from_file
"File {} was not found.".format(filename)
google.auth.exceptions.DefaultCredentialsError: File was not found.
默认服务帐户具有编辑和机密管理器管理员角色(感谢@DanielOcando的评论)。为什么ADC库as不获取默认服务帐户的权限并使用它们来实例化客户端
更新1
@guillaumeblaquiere询问了依赖关系。该容器是使用Python 3.6.12和以下库构建的:
Django==2.1.15
django-admin-rangefilter==0.3.7
django-extensions==2.1.2
django-ipware==1.1.6
pytz==2017.3
psycopg2==2.7.3.2
waitress==1.4.1
geoip2==2.6
gunicorn==19.9.0
social-auth-app-django==3.1.0
semver==2.8.1
sentry-sdk==0.6.9
google-api-core==1.23.0
google-auth==1.23.0
google-cloud-secret-manager==2.0.0
我创建了一个自定义服务帐户,向其中添加了编辑器和Secret Manager管理员角色,然后使用控制台使用该帐户部署了一个新的修订版,但产生了相同的错误
更新2
考虑到在Cloud Shell中匹配CPython版本就可以了,我用Python3.7重建了图像。不走运
更新3
采取不同的策略,我将服务帐户令牌创建者角色添加到项目的默认服务帐户中,创建了一个terraform文件,并将其配置为服务帐户模拟。在调用terraform之前,我还在shell中运行了gcloud auth应用程序默认登录名
provider "google" {
alias = "tokengen"
}
data "google_client_config" "default" {
provider = google.tokengen
}
data "google_service_account_access_token" "sa" {
provider = "google.tokengen"
target_service_account = "XXXXXXXXXXXX-compute@developer.gserviceaccount.com"
lifetime = "600s"
scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
}
provider "google" {
project = "myprojectid-123456"
region = "us-central1"
zone = "us-central1-f"
#impersonate_service_account = "XXXXXXXXXXXX-compute@developer.gserviceaccount.com
}
resource "google_cloud_run_service" "default" {
name = "myprojectid-123456"
location = "us-central1"
template {
spec {
containers {
image = "us.gcr.io/myprojectid-123456/testimage"
}
}
}
traffic {
percent = 100
latest_revision = true
}
}
这确实可以创建服务,但是,当端点尝试实例化SecretManagerServiceClient时,再次出现相同的错误。请注意,如编辑器上所述,
角色不包括secretmanager.versions.access
。我建议你将or角色添加到这个角色中。@DanielOcando当我第一次读到你的评论时,我很有希望。您是对的,Compute Engine默认服务帐户没有相关的Secret Manager权限,但是添加Secret Manager Admin并不能纠正这种情况。令人费解的是,我仍然收到同样的错误。我的下一步行动将是创建一个定制服务帐户,并通过gcloud Run deploy
What's dependencies version?@guillaumeblaquiere我更新了问题,列出了容器中的Python解释器版本和库。我知道Python中新的secret manager库,但我从未测试过。你能试试1.0.0
版本吗?另一个问题可能来自google.auth和google api核心依赖项,它们也用于secret manager依赖项,可能存在冲突。尝试移除它们。