Skip to content

Instantly share code, notes, and snippets.

@arkadijs
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arkadijs/1969f3a02391cc8eca25 to your computer and use it in GitHub Desktop.
Save arkadijs/1969f3a02391cc8eca25 to your computer and use it in GitHub Desktop.
Authentication to Google Compute Engine example
// compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
// compile 'com.google.apis:google-api-services-compute:v1-rev29-1.19.0'
// compile 'com.google.http-client:google-http-client-jackson2:1.19.0'
// compile 'com.google.oauth-client:google-oauth-client-jetty:1.19.0'
import com.google.api.services.compute.Compute
import com.google.api.services.compute.model.*
import wslite.rest.ContentType
import wslite.http.HTTPClient
import wslite.rest.RESTClient
final int tm = 10000 // ms
@Lazy volatile HTTPClient httpClient = new HTTPClient().with { connectTimeout = readTimeout = tm; it }
@Lazy volatile RESTClient metadata = new RESTClient('http://metadata/computeMetadata/v1', httpClient)
Compute initGCEServiceAccount() {
// https://developers.google.com/compute/docs/authentication
// we use GCE Service Account by querying metadata server for an access token
// Alternative: Developer Service Account https://code.google.com/p/google-api-java-client/wiki/OAuth2#Service_accounts
// see Scala example below
def initializer = new com.google.api.client.http.HttpRequestInitializer() {
@Override
void initialize(com.google.api.client.http.HttpRequest request) {
request.headers.setAuthorization(
metadata.get(path: '/instance/service-accounts/default/token',
headers: [ 'X-Google-Metadata-Request': 'true' ], accept: ContentType.JSON)
.json.with { "$token_type $access_token" })
}
}
new com.google.api.services.compute.Compute.Builder(
com.google.api.client.googleapis.javanet.GoogleNetHttpTransport.newTrustedTransport(),
com.google.api.client.json.jackson2.JacksonFactory.getDefaultInstance(), initializer)
.setApplicationName("${grailsApplication.metadata.'app.name'}/${grailsApplication.metadata.'app.version'}")
.build()
}
// Full Oauth2 flow using usual Google user account - on first use, a prompt will be
// issued on the console to perform a manual interaction with Google in browser.
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.client.util.store.FileDataStoreFactory
import com.google.api.services.compute.Compute
import com.google.api.services.compute.ComputeScopes
@Lazy static volatile Compute compute = {
// http://samples.google-api-java-client.googlecode.com/hg/compute-engine-cmdline-sample/instructions.html
// hg clone https://code.google.com/p/google-api-java-client.samples/
// alternatively we may use https://code.google.com/p/google-api-java-client/wiki/ClientLogin (deprecated)
// more info:
// https://code.google.com/p/google-api-java-client/wiki/DeveloperGuide
// https://developers.google.com/resources/api-libraries/documentation/compute/v1/java/latest/
// http://javadoc.google-api-java-client.googlecode.com/hg/1.19.0/index.html
def http = GoogleNetHttpTransport.newTrustedTransport()
def dataStore = new FileDataStoreFactory(new java.io.File(System.getProperty("user.home"), (windows() ? "AppData/Local" : ".cache") + "/myapp_google_compute_engine"))
def json = JacksonFactory.getDefaultInstance()
def secret = GoogleClientSecrets.load(json, new InputStreamReader(getClass().getResourceAsStream("/client_secret.json")))
def flow = new GoogleAuthorizationCodeFlow.Builder(http, json, secret, [ ComputeScopes.COMPUTE ]).setDataStoreFactory(dataStore).build()
def credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user")
new Compute.Builder(http, json, null).setApplicationName("MyApp/1.0").setHttpRequestInitializer(credential).build()
} ()
libraryDependencies ++= Seq(
"com.google.apis" % "google-api-services-compute" % "v1-rev55-1.20.0",
"com.google.http-client" % "google-http-client-jackson2" % "1.20.0",
"org.bouncycastle" % "bcpkix-jdk15on" % "1.52"
)
import java.io.{StringReader, InputStreamReader}
import com.google.api.client.googleapis.auth.oauth2.{GoogleClientSecrets, GoogleCredential}
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.services.compute.{ComputeScopes, Compute}
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
import org.bouncycastle.openssl.PEMParser
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
object GceApiClient {
val project = "my-project-id"
val compute = {
import collection.JavaConversions._
val creds = "/project-service-account.json" // Google Developers Console >> APIs & auth >> Credentials >> Create new Client ID >> Service Account
val http = GoogleNetHttpTransport.newTrustedTransport()
val json = JacksonFactory.getDefaultInstance()
val auth = GoogleClientSecrets.load(json, new InputStreamReader(this.getClass.getResourceAsStream(creds)))
val key = new PEMParser(new StringReader(auth.get("private_key").asInstanceOf[String])).readObject().asInstanceOf[PrivateKeyInfo]
val jcak = new JcaPEMKeyConverter().getPrivateKey(key)
val initializer = new GoogleCredential.Builder().setTransport(http)
.setJsonFactory(json)
.setServiceAccountId(auth.get("client_email").asInstanceOf[String])
.setServiceAccountScopes(List(ComputeScopes.COMPUTE))
.setServiceAccountPrivateKey(jcak)
.build()
new Compute.Builder(http, json, initializer).setApplicationName("ACP/3.0").build()
}
}
GceApiClient.compute.zones().list(GceApiClient.project).execute()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment