I am attempting to programmatically delete an App Engine (Standard) backend instance. The code for deleting it runs as a Servlet on another module/service of the same project.
I am able to list the instance and all the details, but attempting to delete it throws the 403 error.
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Request had insufficient authentication scopes.",
"reason" : "forbidden"
} ],
"message" : "Request had insufficient authentication scopes.",
"status" : "PERMISSION_DENIED"
}
I am using the App engine default service account:
AppIdentityCredential credential = new AppIdentityCredential(Arrays.asList(AppengineScopes.APPENGINE_ADMIN));
Appengine engine = new Appengine.Builder(new UrlFetchTransport(), new JacksonFactory(), credential).setApplicationName("AppEngineManager").build();
//list all instances - this works fine
//now delete an instance
engine.apps().services().versions().instances().delete(appId, serviceId, version, <instanceid>).execute()
The default App engine service account has Editor role (I also tried manually adding App Engine Admin role, to no avail)
The service account name printed before running the code is also correct. What could be wrong?
This solved it!
AppIdentityCredential credential = new AppIdentityCredential(Arrays.asList(AppengineScopes.**CLOUD_PLATFORM**));
I was using the more obvious looking AppengineScopes.APPENGINE_ADMIN, but this doesn't work. Wish Google would improve their documentation. Had sleepless nights because of a production issue which required us to delete the instances programmatically to solve it.
Related
I'm trying to create a GCP App Engine domain mapping via Terraform with the following configuration:
provider "google" {
version = "3.36.0"
region = var.region
}
resource "google_app_engine_domain_mapping" "domain_mapping" {
project = local.project_id
domain_name = var.domain_name
ssl_settings {
ssl_management_type = "AUTOMATIC"
}
depends_on = [
google_app_engine_application.backend_app
]
}
Terraform is configured to use an organization level service account for the GCP provider with the following IAM permissions (no conditions):
Billing Account User
Project Creator
Service Config Editor (I've added this thinking it would resolve the issue based on this and this doc page.)
The Google account that is the owner of the organization has verified the domain in question, yet I'm getting the following error:
Error: Error creating DomainMapping: googleapi: Error 403: Caller is not authorized to administer the domain 'testing.redacted.com'. If you own 'testing.redacted.com', you can obtain authorization by verifying ownership of the domain, or any of its parent domains, via the Webmaster Central portal: https://www.google.com/webmasters/verification/verification?domain=testing.redacted.com. We recommend verifying ownership of the largest scope you wish to use with subdomains (eg. verify 'example.com' if you wish to map 'subdomain.example.com').
I've also tried adding the service account's email as a user in the Google Search Console to the domain to no avail.
The solution is rather simple but sort of hidden in the docs. You need to add your service account email as owner of the domain.
Go here
Select the property you want
Tap the "Add an owner" button at the bottom of the page and add the email address (e.g. terraform#<PROJECT_ID>.iam.gserviceaccount.com)
I am trying to run my application connecting to mysql database in google cloud. But got an exception:
The Application Default Credentials are not available. They are
available if running on Google App Engine, Google Compute Engine, or
Google Cloud Shell. Otherwise, the environment variable
GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file
defining the credentials. See
https://developers.google.com/accounts/docs/application-default-credentials
for more information.
I went to the page and downloaded the json file.Also set up an env variable to the file. Now I have below error:
400 Bad Request { "code" : 400, "errors" : [ { "domain" : "global",
"message" : "Project specified in the request is invalid.", "reason" :
"errorInvalidProject" } ], "message" : "Project specified in the
request is invalid." }
I believe the project id is correct in the json file and not sure what went wrong.
Let me know if you have any questions. Look forward to your reply.
Thanks,
Di
Expected:
My local application should be able to connect to database server in google cloud.
Actual:
get an error saying Project specified in the request is invalid.
UserProjectInvalid The user project specified in the request is invalid, either because it is a malformed project id or because it refers to a non-existent project.
I believe the project id should be correct and it is in the json file I downloaded. I have not modified it.
We're having trouble publishing messages to a Google Cloud PubSub topic on Google AppEngine. Using the Application Default credentials works perfect locally. But once it's deployed on Google AppEngine it gives the following error:
<HttpError 403 when requesting https://pubsub.googleapis.com/v1/projects/our-project-id/topics/our-topic:publish?alt=json returned "The request cannot be identified with a project. Please pass a valid API key with the request.">
I would assume that it's will use the service account of app engine to access the PubSub API. Here is the code we used to create the credentials.
credentials = GoogleCredentials.get_application_default()
if credentials.create_scoped_required():
credentials = credentials.create_scoped(['https://www.googleapis.com/auth/pubsub'])
http = httplib2.Http()
credentials.authorize(http)
pubsub_service = build('pubsub', 'v1', http=http)
The error is thrown when publishing the actual message to PubSub.
pubsub_service.projects().topics().publish(topic="projects/out-project-id/topics/out-topic", body = { 'messages' : [ { 'data': base64.b64encode(request.get_data()) }]}).execute()
Not that the same flow works doing API call's to "BigQuery", so it's not a general Google API problem. It seems to be specific to PubSub...
It's a rare case of the service account without project id embedded in it. We fixed your service account and you should be good to go now. Sorry for the trouble.
My goal is to test out google's orchestrator and the compute engine api by first retrieving a list of active instances. The orchestrator project including the servlet file is stored in a jar.
I'm trying to test out the java google compute engine client api. I have a cron job which calls on the orchestrator servlet. The target for the cron is a backend. From which I try to get the list of instances:
...
AppIdentityCredential credential = getCredential(computeScope);
String appName = ConfigProperties.getInstance().getGceConfigProperties().get("projectId");
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
final Compute compute = new Compute.Builder(
httpTransport, JSON_FACTORY, credential).setApplicationName(appName)
.build();
logger.info("================== Listing Compute Engine Instances ==================");
Compute.Instances.List instances = compute.instances().list(projectId, zone);
InstanceList list = instances.execute();
if (list.getItems() == null) {
logger.info("No instances found. Sign in to the Google APIs Console and create "
+ "an instance at: code.google.com/apis/console");
} else {
for (Instance instance : list.getItems()) {
logger.info(instance.toPrettyString());
}
}
...
There error response I get is(I omitted my project name from the response, I confirmed that I'm using the correct project id in my code):
com.google.cloud.solutions.sampleapps.orchestration.orchestrator.server.GceClientApiUtils
getInstances: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 OK
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"message" : "The resource 'projects/<project-name-here>' was not found",
"reason" : "notFound"
} ],
"message" : "The resource 'projects/<project-name_here>' was not found"
}
I've also attempted this by retrieving an access token and making a RESTful call to get the list of instances and i received the exact same response. I confirmed the Url constructed was correct by comparing it against a successful query of the instances using the api explorer.
EDIT: I determined the solution to the issue with help of another post:
I was finally able to find the solution in the post Compute Engine API call fails with http 404
I needed to add my app engine service account as a team member with edit capabilities, which it does not have by default. Once I did this, the code worked as expected. I had to do this through cloud.google.com/console, as if done through appengine.google.com, a pending status will be given to the service account and will not have access.
For me i had to make sure i had authorization. Try this in the terminal gcloud auth login
Make sure you are in the right project, you can run this command on your vm to see if you are in the right project:
gcloud config list
Take a look at this post in Google Groups
Do you have access to the developers console https://console.developers.google.com?
It seems that the user account #appspot.gserviceaccount.com has not access to compute engine. In my case I see #developer.gserviceaccount.com.
If you don't have one, visit https://developers.google.com/console/help/new/#generatingoauth2 to create a new Client ID
I am using Google App Engine Identity to access Google Drive API of a Google Apps user.
I have inserted GAE URL in Manage API client access in Google Apps, with the right scope.
AppIdentityCredential credential = new AppIdentityCredential(Arrays.asList(DriveScopes.DRIVE_FILE));
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
Drive service = new Drive.Builder(httpTransport, jsonFactory, credential).build();
I get this error:
com.google.appengine.repackaged.org.apache.http.impl.client.DefaultRequestDirector handleResponse
WARNING: Authentication error: Unable to respond to any of these challenges: {authsub=WWW-Authenticate: AuthSub realm="https://www.google.com/accounts/AuthSubRequest" allowed-scopes="https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/docs,https://www.googleapis.com/auth/drive.file,https://www.googleapis.com/auth/drive.readonly,https://www.googleapis.com/auth/drive.metadata.readonly"}
An error occurred: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 OK
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Invalid Credentials",
"reason" : "authError"
} ],
"message" : "Invalid Credentials"
}
Is it necessary to enable GAE application in API Client access in Google Apps? If not, how I authorise GAE app to gain acess to an API Scope?
Is possible to test GAE Identity in Local / Eclipse?
Summarizing, what is wrong or lack?
You can not debug AppEngine Credentials locally. The only way to debug is to use different credentials (AppEngine for production and Key-based service account locally). It will require to write different code for local and production environment.
You need to add your appengine service accounts to Team. If you use custom Google Apps domain for your project than you will need to create email group in your custom domain and add this group. All service accounts should be added to this group.
Consider adding the scopes it tries to authenticate against.
I had the same error in my code and ended up solving in by adding the drive.file scope.
Two important steps
Get the Application Default Credentials Service account JSON file.
Set GOOGLE_APPLICATION_CREDENTIALS environment variable with the path of the JSON file. Example: GOOGLE_APPLICATION_CREDENTIALS=c:/myFolder/my.jsonfile
FYI:
https://developers.google.com/identity/protocols/application-default-credentials