1

I'm able to successfully make GCP calls (e.g. list/create/delete instances) using jclouds, but I'm currently relying on GoogleCredentialsFromJson to supply the credentials. For security reasons (including auto rotation of credentials), I don't want to rely on that in production.

The VM from which I will be making the calls is already associated with a service account, so credentials should not be necessary. However, when I leave out what I thought was an optional Credentials Supplier, I get an error (property google-compute-engine.identity not present in properties). How do I go about wiring jclouds without pointing to credentials?

This works:

        final ContextBuilder contextBuilder = ContextBuilder.newBuilder(GCP_PROVIDER)
                .endpoint(gcpEndpoint)
                .overrides(overrides)
                .credentialsSupplier(newCredentialsSupplier(gcpCredentials))
                .modules(modulesSetBuillder.build());

This does not:

        final ContextBuilder contextBuilder = ContextBuilder.newBuilder(GCP_PROVIDER)
                .endpoint(gcpEndpoint)
                .overrides(overrides)
                .modules(modulesSetBuillder.build());

newCredetialsSupplier essentially just does this:

    // Simplified for this example
    private Supplier<Credentials> newCredentialsSupplier(String jsonCredentials) {
        return new GoogleCredentialsFromJson(jsonCredentials);
    }

I would ideally expect the second code snippet (which just leaves out the credentials supplier) to work, but I get this error instead:

java.util.NoSuchElementException: property google-compute-engine.identity not present in properties: [jclouds.idempotent-methods, jclouds.user-threads, jclouds.template, jclouds.max-session-failures, oauth.endpoint, jclouds.google-compute-engine.image-projects, jclouds.google-compute-engine.operation-complete-timeout, jclouds.oauth.jws-alg, jclouds.max-connection-reuse, jclouds.endpoint, jclouds.connection-close-header, jclouds.googlecloud.project-name, jclouds.scheduler-threads, jclouds.build-version, jclouds.iso3166-codes, jclouds.google-compute-engine.operation-complete-interval, jclouds.so-timeout, jclouds.max-connections-per-host, jclouds.max-connections-per-context, jclouds.strip-expect-header, jclouds.regions, jclouds.api, jclouds.user-agent, jclouds.max-parallel-deletes, jclouds.oauth.audience, jclouds.api-version, jclouds.payloads.pretty-print, jclouds.connection-timeout, jclouds.provider, jclouds.session-interval]"}
Danny
  • 11
  • 1
  • This link has code examples. You want to use ComputeEngine.create() to grab the credentials from the GCE instance metadata: https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-java – John Hanley May 24 '19 at 04:05
  • @JohnHanley, I appreciate the response, but I'm trying to do this with Apache jclouds, not native GCP client libraries. The link you provided points to a GCP client library example. Am I misunderstanding your reply? – Danny May 24 '19 at 18:44
  • I am confused about where the code is running and what VM has the service account attached? A service account is assigned to a GCE instance. The credentials are accessed from the metadata. This metadata is not available outside the instance. If your code is running somewhere else, then you will have to load the service account JSON file yourself. Note: I don't know anything about jclouds, just how security and permissions are managed inside GCP. – John Hanley May 24 '19 at 19:16
  • Thanks John. This is a jclouds-specific question. jclouds is an abstraction layer that lets you integrate with multiple cloud providers. My application is already capable of running on OpenStack, AWS, and now GCP. It's currently running on a GCE instance, but I cannot get it to run without a JSON file, which should be unnecessary because the credentials should be available from the instance's metadata, as you have pointed out yourself. I'm trying to figure out if there's already a way, or if I need to contribute to jclouds to make this work.... Thanks for the replies/comments though! – Danny May 27 '19 at 15:50
  • Thanks Danny. I have written a lot of articles on GCP credentials on my website. These might help you with understanding GCP authorization. – John Hanley May 27 '19 at 15:55
  • @Danny I stumbled on the same issue, did you managed to find a workaround? @JohnHanley I think that your first comment is a good first step. After calling the `ComputeEngine.create()` is there a way to get a `String` object containing the same data than the content of the `GOOGLE_APPLICATION_CREDENTIALS` file? – AlexisBRENON Oct 04 '21 at 06:54
  • @AlexisBRENON - The metadata server (accessible within a compute service) does not provide the private key, only OAuth tokens. Therefore, you cannot fetch the equivalent of the service account JSON key, only credentials created from the JSON key. – John Hanley Oct 04 '21 at 17:33
  • @JohnHanley I reported the [issue to jclouds](https://issues.apache.org/jira/browse/JCLOUDS-1585), hoping that they support another kind of credentials. – AlexisBRENON Oct 05 '21 at 07:29

0 Answers0