如何以编程方式在 Google 云 运行 api 中获取当前项目 ID

How to programmatically get current project id in Google cloud run api

我有一个容器化的 API 并且 运行 在云中 运行。如何获取我的云 运行 正在执行的当前项目 ID?我试过:

还有别的办法吗?

编辑:

在下面的一些评论之后,我最终在我的 .net API 运行ning 中使用了这段代码 Cloud 运行

        private string GetProjectid()
        {
            var projectid = string.Empty;
            try {
                var PATH = "http://metadata.google.internal/computeMetadata/v1/project/project-id";
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("Metadata-Flavor", "Google");
                    projectid = client.GetStringAsync(PATH).Result.ToString();
                }

                Console.WriteLine("PROJECT: " + projectid);
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message + " --- " + ex.ToString());
            }
            return projectid;
        }

更新,有效。我的构建推送失败了,我没有看到。感谢大家。

  1. 我按照教程做了Using Pub/Sub with Cloud Run tutorial

  2. 我添加到 requirements.txt 模块 gcloud

       Flask==1.1.1
       pytest==5.3.0; python_version > "3.0"
       pytest==4.6.6; python_version < "3.0"
       gunicorn==19.9.0
       gcloud
    
  3. 我在 main.py 中更改了 index 函数:

       def index():
         envelope = request.get_json()
         if not envelope:
            msg = 'no Pub/Sub message received'
            print(f'error: {msg}')
            return f'Bad Request: {msg}', 400
         if not isinstance(envelope, dict) or 'message' not in envelope:
            msg = 'invalid Pub/Sub message format'
            print(f'error: {msg}')
            return f'Bad Request: {msg}', 400
         pubsub_message = envelope['message']
         name = 'World'
         if isinstance(pubsub_message, dict) and 'data' in pubsub_message:
            name = base64.b64decode(pubsub_message['data']).decode('utf-8').strip()
         print(f'Hello {name}!')
    
         #code added 
         from gcloud import pubsub  # Or whichever service you need
         client = pubsub.Client()
         print('This is the project {}'.format(client.project))
    
         # Flush the stdout to avoid log buffering.
         sys.stdout.flush()
         return ('', 204)
    
    1. 我查看了日志:

        Hello (pubsub message).
        This is the project my-project-id.
      

您可以通过使用 Metadata-Flavor:Google header 向 http://metadata.google.internal/computeMetadata/v1/project/project-id 发送 GET 请求来获取项目 ID。

this documentation

在Node.js例如:

index.js:

const express = require('express');
const axios = require('axios');
const app = express();

const axiosInstance = axios.create({
  baseURL: 'http://metadata.google.internal/',
  timeout: 1000,
  headers: {'Metadata-Flavor': 'Google'}
});

app.get('/', (req, res) => {
  let path = req.query.path || 'computeMetadata/v1/project/project-id';
  axiosInstance.get(path).then(response => {
    console.log(response.status)
    console.log(response.data);
    res.send(response.data);
  });
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});

package.json:

{
  "name": "metadata",
  "version": "1.0.0",
  "description": "Metadata server",
  "main": "app.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "axios": "^0.18.0",
    "express": "^4.16.4"
  }
}

应该可以使用 Google.Api.Gax (https://github.com/googleapis/gax-dotnet/blob/master/Google.Api.Gax/Platform.cs) 中的 Platform class。 Google.Api.Gax 包通常作为其他 Google .NET 包的依赖项安装,例如 Google.Cloud.Storage.V1

var projectId = Google.Api.Gax.Platform.Instance().ProjectId;

在GAE平台上,也可以简单查看环境变量GOOGLE_CLOUD_PROJECTGCLOUD_PROJECT

var projectId = Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT")
             ?? Environment.GetEnvironmentVariable("GCLOUD_PROJECT");

这是获取当前项目 ID 的 Java 代码片段:

            String url = "http://metadata.google.internal/computeMetadata/v1/project/project-id";
            HttpURLConnection conn = (HttpURLConnection)(new URL(url).openConnection());
            conn.setRequestProperty("Metadata-Flavor", "Google");
            try {
                InputStream in = conn.getInputStream();
                projectId = new String(in.readAllBytes(), StandardCharsets.UTF_8);
            } finally {
                conn.disconnect();
            }               

其他人已经展示了如何通过 HTTP API 获取项目名称,但在我看来,这里更容易、更简单、性能更高的方法是将项目 ID 设置为 run-time environment variable.为此,当您部署函数时:

gcloud functions deploy myFunction --set-env-vars PROJECT_ID=my-project-name

然后您可以使用如下代码访问它:

exports.myFunction = (req, res) => {
  console.log(process.env.PROJECT_ID);
}

您只需为部署函数的每个环境设置适当的值。这有一个非常小的缺点,即需要为每个环境提供一次性命令行参数,而非常主要的优点是不使您的函数依赖于成功验证和解析 API 响应。这也提供了代码可移植性,因为几乎所有托管环境都支持环境变量,包括您的本地开发环境。

@Steren 在 python

中的回答
import os

def get_project_id():
    # In python 3.7, this works
    project_id = os.getenv("GCP_PROJECT")

    if not project_id:  # > python37
        # Only works on runtime.
        import urllib.request

        url = "http://metadata.google.internal/computeMetadata/v1/project/project-id"
        req = urllib.request.Request(url)
        req.add_header("Metadata-Flavor", "Google")
        project_id = urllib.request.urlopen(req).read().decode()

    if not project_id:  # Running locally
        with open(os.environ["GOOGLE_APPLICATION_CREDENTIALS"], "r") as fp:
            credentials = json.load(fp)
        project_id = credentials["project_id"]

    if not project_id:
        raise ValueError("Could not get a value for PROJECT_ID")

    return project_id