Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BEAM-582] Allow usage of the new GCP service account JSON key #879

Closed
wants to merge 1 commit into from
Closed

[BEAM-582] Allow usage of the new GCP service account JSON key #879

wants to merge 1 commit into from

Conversation

alexvanboxel
Copy link
Contributor

Allow the usage of the more modern JSON files on the GCP. This required for seamless integration planned in Apache Airflow 1.8

@@ -137,13 +138,27 @@ public static Credential getCredential(GcpOptions options)
private static Credential getCredentialFromFile(
String keyFile, String accountId, Collection<String> scopes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mark keyFile to be @Nullable based on your change above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and accountId actually

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accountId is @nullable depending on the type of key (keyFile is not in the getCredentialFromFile)

@dhalperi
Copy link
Contributor

Thanks, this is interesting!

@alexvanboxel
Copy link
Contributor Author

That's a fast review. Will fix it tomorrow.

@alexvanboxel
Copy link
Contributor Author

I think the travis build failure is unrelated. As soon as it's approved I'll submit a back-port to Cloud DataFlow.


if (keyFile == null) {
throw new IOException("If accountName is given, also supply a keyFile");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Alex, I'm clearly missing something here. It looks like from the code at L141 that keyFile MUST be non-null to enter this function. But the change you made at L111 makes it okay to call this function if keyFile is null.

Should L111 maybe just be if (keyFile != null) ? Then we can remove @Nullable from the parameter here.

Copy link
Contributor Author

@alexvanboxel alexvanboxel Aug 26, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that all these options are given via the command line: so we can expect null's (and want to check all the permutations in this function). So what is valid:

p12 keyfile + accountName
json keyfile : NO accountName

the rest is invalid. (I've added all the errors in the test.

So the scenario were handling here is (you have given a accountName, but an accountName is not enough, you need a keyFile):

  @Test
  public void testAccountNameWithoutKeyFile() throws Exception {
    GcpOptions options = PipelineOptionsFactory.as(GcpOptions.class);
    options.setServiceAccountName("test@gcloud");

    thrown.expect(IOException.class);
    thrown.expectMessage(new StringContains("also supply a keyFile"));
    GcpCredentialFactory.fromOptions(options).getCredential();
  }

Hope it makes sense?!

Copy link
Contributor

@dhalperi dhalperi Aug 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, that makes sense.

For visible clarity, I'd prefer if we refactored something like this around L111:

if (keyFile != null) {
   get the credentials;
} else if (account != null) {
   throw IOException("If accountName is given, also supply a keyFile');
}

then we can remove the @Nullable from the keyFile parameter to this function. I think it will make the code generally easier to read and understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that doesn't cover all scenario's. But I think I a pushed something that covers all remarks:

In:

  • getCredential(GcpOptions options) -> keyFile or accountName is give -> check at least that the keyFile is given (required for JSON and P12)
  • getCredentialFromFile -> check the JSON case (no accountName allowed) or 12 case (accountName required)

Because keyFile is checked of in getCredential @nullable could be removed from keyFile in getCredentialFromFile.

@alexvanboxel
Copy link
Contributor Author

Global recap (because comment on changed code is hidden):

getCredential(GcpOptions options) -> keyFile or accountName is give -> check at least that the keyFile is given (required for JSON and P12)
getCredentialFromFile -> check if it's a JSON keyFile (no accountName allowed) or p12 keyFile (accountName required)

Because keyFile is checked of in getCredential @nullable could be removed from keyFile in getCredentialFromFile.

@lukecwik
Copy link
Member

gcloud-java-core would subsume this logic and more, opened up issue against gcloud-java-core for exposing default project/default auth: googleapis/google-cloud-java#1207

@alexvanboxel
Copy link
Contributor Author

@lukecwik if you mean "default" auth, I'm thinking of the credentials set by the gcloud command on a local machine. My scenario is this:

I'm running a lot GCP services via Airflow (DataProc, BigQuery, Storage and DataFlow). They are all running in a Kubernetes cluster using a service-key generated via the console (JSON file). The problem I have is that the containers don't have gcloud command installed, so I need to pass the service-key (JSON) file as a parameter to the jar (I'm always packing everything in a single JAR), but currently there is only support for the P12 (old keyfiles). Hence the PR.

@lukecwik
Copy link
Member

We already support using JSON files via default auth:
https://developers.google.com/identity/protocols/application-default-credentials
Just requires you to set GOOGLE_APPLICATION_CREDENTIALS env variable to point to the json file.

Integrating with gcloud-java-core would add the benefit of allowing us to get the project id from the credentials when using service accounts and not need to rely for users to specify it.

@alexvanboxel
Copy link
Contributor Author

@lukecwik : thanks for clarifying. Learned something new today. I'm going to try playing with the env variable. But does this block this block this PR? Also remember the accountName != projectId. The accountName you need to specify with the P12 keys (not at all required with JSON files).

Currently I don't have the bandwidth to dive into gcloud-java-core. So I probably abandon the PR for now and experiment with setting the GOOGLE_APPLICATION_CREDENTIALS in the Apache Airflow DataFlowJavaOperator.

@lukecwik
Copy link
Member

lukecwik commented Sep 1, 2016

Yes I understand that account name != project id, I was just saying that integrating with gcloud-java-core would also improve our experience since they expose more methods for credentials.

@dhalperi
Copy link
Contributor

R: @lukecwik

(just updating metadata)

@lukecwik
Copy link
Member

lukecwik commented Nov 7, 2016

This is being superseded by BEAM-725 with PR #1294

@nssalian
Copy link

@alexvanboxel could you please close this PR.

@alexvanboxel
Copy link
Contributor Author

Abandoning...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants