【问题标题】:Get Runtime Service Account running a Cloud Function获取运行云函数的运行时服务帐户
【发布时间】:2021-04-23 09:18:51
【问题描述】:

有没有办法以编程方式从云函数中获取运行时服务帐户的电子邮件?

我知道我可以“猜测”默认 App Engine 帐户(因为它始终是 @appspot.gserviceaccount.com),但这不是我想要的。

我希望有一些 Environment Variable 或带有此信息的东西,但我找不到任何东西。

【问题讨论】:

    标签: python google-cloud-functions


    【解决方案1】:

    对于较旧的运行时(Node.js 8、Python 3.7 和 Go 1.11),您可以使用 FUNCTION_IDENTITY 环境变量,如 described here

    Python 示例:

    import os
    service_account_email = os.environ.get('FUNCTION_IDENTITY')
    

    对于较新的运行时,您需要查询Metadata Server,如下例所示:

    import requests
    def query_metadata(entry):
        response = requests.get('http://metadata.google.internal/computeMetadata/v1/' + entry, headers={'Metadata-Flavor': 'Google'})
        return response.content.decode("utf-8")
    
    service_account_email = query_metadata('instance/service-accounts/default/email')
    

    您还可以编写一个同时支持运行时(旧的和新的)的函数,使用:

    service_account_email = os.environ.get('FUNCTION_IDENTITY') or query_metadata('instance/service-accounts/default/email')
    

    有关可用于查询信息的元数据端点列表,check here

    【讨论】:

      【解决方案2】:

      如果您使用的是较新的运行时,则可以使用 REST API 以编程方式获取 Cloud Function 的运行时服务帐号。这是一个基于 answer 的示例:

      import requests
      import json
      
      def get_sa():
        FUNCTION_NAME = 'func_name'
        PROJECT_ID = 'proj_id'
        REGION = 'us-central1'
      
        # Get the access token from the metadata server
        metadata_server_token_url = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token?scopes=https://www.googleapis.com/auth/cloud-platform'
        token_request_headers = {'Metadata-Flavor': 'Google'}
        token_response = requests.get(metadata_server_token_url, headers=token_request_headers)
        token_response_decoded = token_response.content.decode("utf-8")
        access_token = json.loads(token_response_decoded)['access_token']
      
        # Call functions.get() to retrieve Cloud Functions information
        response = requests.get('https://cloudfunctions.googleapis.com/v1/projects/{}/locations/{}/functions/{}'.format(PROJECT_ID, REGION, FUNCTION_NAME),
          headers={
            'Accept': 'application/json', 
            'Content-Type': 'application/json',
            'Authorization': 'Bearer {}'.format(access_token)
            })   
        print(response.json()['serviceAccountEmail'])
      
      get_sa()
      

      请注意,如果您的应用部署在 GCP(Compute Engine、Cloud Functions 等)中,您只能从元数据服务器获取访问令牌。如果您的应用位于本地计算机上,则需要使用服务帐户和身份验证库来生成访问令牌。如果您使用的是 Python,这里是 auth 库 reference

      要了解有关给定 REST API 方法的更多信息,请参阅projects.locations.functions.get()

      【讨论】:

      • 您的解决方案很有趣,但迫使我对函数名称、项目和区域进行硬编码,这导致我遇到同样的问题:如果是这种情况,只需使用代码中的电子邮件。
      猜你喜欢
      • 2022-08-17
      • 2020-04-20
      • 2021-03-25
      • 2021-03-04
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      相关资源
      最近更新 更多