I have an API that is containerized and running inside cloud run. How can I get the current project ID where my cloud run is executing? I have tried:
Is there any other way?
Edit:
After some comments below, I ended up with this code inside my .net API running inside Cloud Run .
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;
}
Update, it works. My build pushes had been failing and I did not see. Thanks everyone.
You get the project ID by sending an GET request to http://metadata.google.internal/computeMetadata/v1/project/project-id
with the Metadata-Flavor:Google
header.
In Node.js for example:
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"
}
}
I followed the tutorial Using Pub/Sub with Cloud Run tutorial
I added to the requirements.txt
the module 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
I changed index
function in main.py:
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)
I checked the logs:
Hello (pubsub message). This is the project my-project-id.
Here is a snippet of Java code that fetches the current project ID:
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();
}
Others have shown how to get the project name via HTTP API, but in my opinion the easier, simpler, and more performant thing to do here is to just set the project ID as a run-time environment variable . To do this, when you deploy the function:
gcloud functions deploy myFunction --set-env-vars PROJECT_ID=my-project-name
And then you would access it in code like:
exports.myFunction = (req, res) => {
console.log(process.env.PROJECT_ID);
}
You would simply need to set the proper value for each environment where you deploy the function. This has the very minor downside of requiring a one-time command line parameter for each environment, and the very major upside of not making your function depend on successfully authenticating with and parsing an API response. This also provides code portability, because virtually all hosting environments support environment variables, including your local development environment.
@Steren 's answer in 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
official Google's client library:
import gcpMetadata from 'gcp-metadata'
const projectId = await gcpMetadata.project('project-id')
It should be possible to use the Platform
class from Google.Api.Gax
( https://github.com/googleapis/gax-dotnet/blob/master/Google.Api.Gax/Platform.cs ). The Google.Api.Gax
package is usually installed as dependency for the other Google .NET packages like Google.Cloud.Storage.V1
var projectId = Google.Api.Gax.Platform.Instance().ProjectId;
On the GAE platform, you can also simply check environment variables GOOGLE_CLOUD_PROJECT
and GCLOUD_PROJECT
var projectId = Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT")
?? Environment.GetEnvironmentVariable("GCLOUD_PROJECT");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.