如何以编程方式在 Google 云 运行 api 中获取当前项目 ID
How to programmatically get current project id in Google cloud run api
我有一个容器化的 API 并且 运行 在云中 运行。如何获取我的云 运行 正在执行的当前项目 ID?我试过:
- 我在日志的 textpayload 中看到它,但我不确定如何读取 post 函数中的 textpayload?我收到的发布订阅消息缺少此信息。
- 我已经阅读了查询元数据 api,但不太清楚如何从 api 中再次执行此操作。有链接吗?
还有别的办法吗?
编辑:
在下面的一些评论之后,我最终在我的 .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;
}
更新,有效。我的构建推送失败了,我没有看到。感谢大家。
我添加到 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
我在 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)
我查看了日志:
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。
在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_PROJECT
和GCLOUD_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
我有一个容器化的 API 并且 运行 在云中 运行。如何获取我的云 运行 正在执行的当前项目 ID?我试过:
- 我在日志的 textpayload 中看到它,但我不确定如何读取 post 函数中的 textpayload?我收到的发布订阅消息缺少此信息。
- 我已经阅读了查询元数据 api,但不太清楚如何从 api 中再次执行此操作。有链接吗?
还有别的办法吗?
编辑:
在下面的一些评论之后,我最终在我的 .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;
}
更新,有效。我的构建推送失败了,我没有看到。感谢大家。
我添加到
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
我在 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)
我查看了日志:
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。
在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_PROJECT
和GCLOUD_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