about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2018-06-14T14·48+0200
committerVincent Ambo <mail@tazj.in>2018-06-14T14·48+0200
commit2d8e057118c527cc1697327db00d4006d8530b91 (patch)
tree2c89e2ff1fbf7e2ed0a814c7ffcc7fca8c55fed4
parent2541d25fbaa28b81045f9809c4b71565c6de3f51 (diff)
feat(main): Add fetching of tokens from metadata server
-rw-r--r--src/main.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 007dd6e629b2..c6cfa8df1e76 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,10 +14,17 @@ mod stackdriver;
 
 use std::env;
 use std::mem;
+use std::ops::Add;
 use std::process;
 use std::time::{Duration, Instant};
 use systemd::journal::*;
 
+const METADATA_TOKEN_URL: &str = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token";
+
+header! { (MetadataFlavor, "Metadata-Flavor") => [String] }
+
+type Result<T> = std::result::Result<T, failure::Error>;
+
 #[derive(Debug)]
 struct Record {
     message: Option<String>,
@@ -90,6 +97,38 @@ fn flush(records: Vec<Record>) {
     }
 }
 
+/// Retrieves an access token from the GCP metadata service.
+#[derive(Deserialize)]
+struct TokenResponse {
+    #[serde(rename = "type")]
+    expires_in: u64,
+    access_token: String,
+}
+
+/// Struct used to store a token together with a sensible
+/// representation of when it expires.
+struct Token {
+    token: String,
+    renew_at: Instant,
+}
+
+fn get_metadata_token(client: &reqwest::Client) -> Result<Token> {
+    let now = Instant::now();
+
+    let token: TokenResponse  = client.get(METADATA_TOKEN_URL)
+        .header(MetadataFlavor("Google".into()))
+        .send()?.json()?;
+
+    debug!("Fetched new token from metadata service");
+
+    let renew_at = now.add(Duration::from_secs(token.expires_in / 2));
+
+    Ok(Token {
+        renew_at,
+        token: token.access_token,
+    })
+}
+
 fn main () {
     env_logger::init();