apardue1
apardue1

Reputation: 51

Setting GOOGLE_APPLICATION_CREDENTIALS in CURRENT shell session via node.js

Overview:

I'm building out automation in my prod deployment to GCP and subsequently GCS via Node.js v8.12.0. The beginning of this deployment process requires me to do the following:

  1. Traverse the folders and files in the project folder to find the GCS service account JSON key file.

  2. Identify location of said key file.

  3. Run export GOOGLE_APPLICATION_CREDENTIALS="/path/to/file/[FILE_NAME].json" to set location so I can execute code to call GCS functions via node.

I've tried executing a command via child_process.exec module in node.js. The execution is successful but in a alternate shell.

Per the google documentation, setting the GOOGLE_APPLICATION_CREDENTIALS variable "...only applies to your current shell session, so if you open a new session, set the variable again."

Although it doesn't take a ton of time to set, I'd like to automate this during the deployment process. So is there a way for me to execute this in the current shell? Open to other ideas as well.

code below:

const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
var readFileTree = require('read-file-tree');
const prompts = require('prompts');
const find = require('find-file-up');
// var tty = require('tty');
var program = require('commander');
const { exec } = require('child_process');
const chalk = require('chalk');
var gsBuckets = {};
var i = 0;
    

function findOauthJSON () {
console.log("Finding your service account keys...")
 find('fauxfile_1123456ae.json', 'a/b/c', function(err, file) {
     if (file !== undefined) {
           console.log("Service keys found: ",file);
           setOathJSON(file);
     } else if (err !== undefined) {
         
         console.log(err);
     } else {
         
         console.log("Couldn't find your service account keys.  Add to your folders and try again.")
     }

});

}

function setOathJSON (file) {
    console.log("Setting service key pay to access GCS...");


var command = 'export GOOGLE_APPLICATION_CREDENTIALS=\"'+file+'\"';

exec(command, (err, stdout, stderr) => {
  if (err === null) {
    console.log("Service key set!");
  }

  // the *entire* stdout and stderr (buffered)
  console.log(`stdout: ${stdout}`);
  console.log(`stderr: ${stderr}`);
  console.log(`err: ${err}`);
  console.log("cmd: "+command);
});
}

function gstoreInfo () {
  
console.log("Getting cloud storage info...");
storage
  .getBuckets()
  .then(results => {
    const buckets = results[0];
    
    buckets.forEach(bucket => {
      gsBuckets["gstoreb"+i] = bucket.name;
      console.log("Found bucket: "+bucket.name);
      i++;
    });
  })
    .catch(err => {
    console.error('ERROR:', err);
  });
  
}

Upvotes: 2

Views: 3935

Answers (1)

apardue1
apardue1

Reputation: 51

Figured it out. The Node idiomatic Libraries allow you to set the keyFileName path via the instantiated storage object like so:

const storage = new Storage({
  projectId: 'mystorage-bucket-123456',
  keyFilename: ''/path/to/keyfile.json''
});

This documentation is a bit hidden but you can be find it here: https://github.com/googleapis/google-cloud-node/blob/master/docs/authentication.md

Anytime you call storage, the keyFilename is passed for authentication. I used the same code as above and it worked.

Upvotes: 3

Related Questions