Files
google-auth-library-nodejs/lib/auth/computeclient.js
Jonathan Wayne Parrott 610ab17ad4 Use full compute metadata DNS name
Use the `metadata.google.internal` instead of just `metadata`. This enables Compute Engine auth to work on Kubernetes, Container Engine,  and Container-Optimized VMs and setups with custom DNS servers. Otherwise, the DNS lookup for `metadata` will fail.
2015-11-12 10:55:11 -08:00

130 lines
4.0 KiB
JavaScript

/**
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
var Auth2Client = require('./oauth2client.js');
var util = require('util');
/**
* Google Compute Engine metadata server token endpoint.
* @private
*/
Compute.GOOGLE_OAUTH2_TOKEN_URL_ =
'http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token';
/**
* Google Compute Engine service account credentials.
*
* Retrieve access token from the metadata server.
* See: https://developers.google.com/compute/docs/authentication
* @constructor@constructor
*/
function Compute() {
Compute.super_.call(this);
// Start with an expired refresh token, which will automatically be refreshed
// before the first API call is made.
this.credentials = {
refresh_token: 'compute-placeholder',
expiry_date: 1
};
// Hook the post request method so we can provide better error messages.
this._postRequest = this._injectErrorMessage;
}
/**
* Inherit from Auth2Client.
*/
util.inherits(Compute, Auth2Client);
/**
* Indicates whether the credential requires scopes to be created by calling createdScoped before
* use.
* @return {object} The cloned instance.
*/
Compute.prototype.createScopedRequired = function() {
// On compute engine, scopes are specified at the compute instance's creation time,
// and cannot be changed. For this reason, always return false.
return false;
};
/**
* Refreshes the access token.
* @param {object=} ignored_
* @param {function=} opt_callback Optional callback.
* @private
*/
Compute.prototype.refreshToken_ = function(ignored_, opt_callback) {
var uri = this.opts.tokenUrl || Compute.GOOGLE_OAUTH2_TOKEN_URL_;
// request for new token
this.transporter.request({
method: 'GET',
uri: uri,
json: true
}, function(err, tokens, response) {
if (!err && tokens && tokens.expires_in) {
tokens.expiry_date = ((new Date()).getTime() + (tokens.expires_in * 1000));
delete tokens.expires_in;
}
if (opt_callback) {
opt_callback(err, tokens, response);
}
});
};
/**
* Inserts a helpful error message guiding the user toward fixing common auth issues.
* @param {object} err Error result.
* @param {object} result The result.
* @param {object} response The HTTP response.
* @param {Function} callback The callback.
* @private
*/
Compute.prototype._injectErrorMessage = function(err, result, response, callback) {
if (response && response.statusCode) {
var helpfulMessage = null;
if (response.statusCode === 403) {
helpfulMessage = 'A Forbidden error was returned while attempting to retrieve an access ' +
'token for the Compute Engine built-in service account. This may be because the Compute ' +
'Engine instance does not have the correct permission scopes specified.';
} else if (response.statusCode === 404) {
helpfulMessage = 'A Not Found error was returned while attempting to retrieve an access' +
'token for the Compute Engine built-in service account. This may be because the Compute ' +
'Engine instance does not have any permission scopes specified.';
}
if (helpfulMessage) {
if (err && err.message) {
helpfulMessage += ' ' + err.message;
}
if (err) {
err.message = helpfulMessage;
} else {
err = new Error(helpfulMessage);
err.code = response.statusCode;
}
}
}
callback(err, result, response);
};
/**
* Export Compute.
*/
module.exports = Compute;