gcp-metadata
Advanced tools
Comparing version 0.7.0 to 0.8.0
@@ -1,2 +0,7 @@ | ||
import { AxiosRequestConfig, AxiosResponse } from 'axios'; | ||
/** | ||
* Copyright 2018 Google LLC | ||
* | ||
* Distributed under MIT license. | ||
* See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | ||
*/ | ||
export declare const HOST_ADDRESS = "http://metadata.google.internal"; | ||
@@ -10,9 +15,10 @@ export declare const BASE_PATH = "/computeMetadata/v1"; | ||
}>; | ||
export declare type Options = AxiosRequestConfig & { | ||
[index: string]: {} | string | undefined; | ||
export interface Options { | ||
params?: { | ||
[index: string]: string; | ||
}; | ||
property?: string; | ||
uri?: string; | ||
}; | ||
export declare function instance(options?: string | Options): Promise<AxiosResponse<any>>; | ||
export declare function project(options?: string | Options): Promise<AxiosResponse<any>>; | ||
} | ||
export declare function instance<T = any>(options?: string | Options): Promise<T>; | ||
export declare function project<T = any>(options?: string | Options): Promise<T>; | ||
/** | ||
@@ -19,0 +25,0 @@ * Determine if the metadata server is currently available. |
"use strict"; | ||
/** | ||
* Copyright 2018 Google LLC | ||
* | ||
* Distributed under MIT license. | ||
* See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | ||
*/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -10,44 +16,6 @@ return new (P || (P = Promise))(function (resolve, reject) { | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var _a; | ||
var axios_1 = __importDefault(require("axios")); | ||
var extend_1 = __importDefault(require("extend")); | ||
var rax = __importStar(require("retry-axios")); | ||
const axios_1 = require("axios"); | ||
const rax = require("retry-axios"); | ||
const jsonBigint = require('json-bigint'); | ||
exports.HOST_ADDRESS = 'http://metadata.google.internal'; | ||
@@ -58,63 +26,70 @@ exports.BASE_PATH = '/computeMetadata/v1'; | ||
exports.HEADER_VALUE = 'Google'; | ||
exports.HEADERS = Object.freeze((_a = {}, _a[exports.HEADER_NAME] = exports.HEADER_VALUE, _a)); | ||
// Accepts an options object passed from the user to the API. In the | ||
// previous version of the API, it referred to a `Request` options object. | ||
// Now it refers to an Axios Request Config object. This is here to help | ||
// ensure users don't pass invalid options when they upgrade from 0.4 to 0.5. | ||
exports.HEADERS = Object.freeze({ [exports.HEADER_NAME]: exports.HEADER_VALUE }); | ||
// Accepts an options object passed from the user to the API. In previous | ||
// versions of the API, it referred to a `Request` or an `Axios` request | ||
// options object. Now it refers to an object with very limited property | ||
// names. This is here to help ensure users don't pass invalid options when | ||
// they upgrade from 0.4 to 0.5 to 0.8. | ||
function validate(options) { | ||
var vpairs = [ | ||
{ invalid: 'uri', expected: 'url' }, { invalid: 'json', expected: 'data' }, | ||
{ invalid: 'qs', expected: 'params' } | ||
]; | ||
for (var _i = 0, vpairs_1 = vpairs; _i < vpairs_1.length; _i++) { | ||
var pair = vpairs_1[_i]; | ||
if (options[pair.invalid]) { | ||
var e = "'" + pair.invalid + "' is not a valid configuration option. Please use '" + pair.expected + "' instead. This library is using Axios for requests. Please see https://github.com/axios/axios to learn more about the valid request options."; | ||
throw new Error(e); | ||
Object.keys(options).forEach(key => { | ||
switch (key) { | ||
case 'params': | ||
case 'property': | ||
break; | ||
case 'qs': | ||
throw new Error(`'qs' is not a valid configuration option. Please use 'params' instead.`); | ||
default: | ||
throw new Error(`'${key}' is not a valid configuration option.`); | ||
} | ||
} | ||
}); | ||
} | ||
function metadataAccessor(type, options, noResponseRetries) { | ||
if (noResponseRetries === void 0) { noResponseRetries = 3; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var property, ax, baseOpts, reqOpts; | ||
return __generator(this, function (_a) { | ||
options = options || {}; | ||
if (typeof options === 'string') { | ||
options = { property: options }; | ||
function metadataAccessor(type, options, noResponseRetries = 3) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
options = options || {}; | ||
if (typeof options === 'string') { | ||
options = { property: options }; | ||
} | ||
let property = ''; | ||
if (typeof options === 'object' && options.property) { | ||
property = '/' + options.property; | ||
} | ||
validate(options); | ||
const ax = axios_1.default.create({ | ||
transformResponse: [t => t] // Do not use default JSON.parse. | ||
}); | ||
rax.attach(ax); | ||
const reqOpts = { | ||
url: `${exports.BASE_URL}/${type}${property}`, | ||
headers: Object.assign({}, exports.HEADERS), | ||
raxConfig: { noResponseRetries, instance: ax }, | ||
params: options.params | ||
}; | ||
try { | ||
const res = yield ax.request(reqOpts); | ||
// NOTE: node.js converts all incoming headers to lower case. | ||
if (res.headers[exports.HEADER_NAME.toLowerCase()] !== exports.HEADER_VALUE) { | ||
throw new Error(`Invalid response from metadata service: incorrect ${exports.HEADER_NAME} header.`); | ||
} | ||
property = ''; | ||
if (typeof options === 'object' && options.property) { | ||
property = '/' + options.property; | ||
else if (!res.data) { | ||
throw new Error('Invalid response from the metadata service'); | ||
} | ||
validate(options); | ||
ax = axios_1.default.create(); | ||
rax.attach(ax); | ||
baseOpts = { | ||
url: exports.BASE_URL + "/" + type + property, | ||
headers: Object.assign({}, exports.HEADERS), | ||
raxConfig: { noResponseRetries: noResponseRetries, instance: ax } | ||
}; | ||
reqOpts = extend_1.default(true, baseOpts, options); | ||
delete reqOpts.property; | ||
return [2 /*return*/, ax.request(reqOpts) | ||
.then(function (res) { | ||
// NOTE: node.js converts all incoming headers to lower case. | ||
if (res.headers[exports.HEADER_NAME.toLowerCase()] !== exports.HEADER_VALUE) { | ||
throw new Error("Invalid response from metadata service: incorrect " + exports.HEADER_NAME + " header."); | ||
} | ||
else if (!res.data) { | ||
throw new Error('Invalid response from the metadata service'); | ||
} | ||
return res; | ||
}) | ||
.catch(function (err) { | ||
if (err.response && err.response.status !== 200) { | ||
err.message = 'Unsuccessful response status code. ' + err.message; | ||
} | ||
throw err; | ||
})]; | ||
}); | ||
if (typeof res.data === 'string') { | ||
try { | ||
return jsonBigint.parse(res.data); | ||
} | ||
catch (_a) { | ||
/* ignore */ | ||
} | ||
} | ||
return res.data; | ||
} | ||
catch (e) { | ||
if (e.response && e.response.status !== 200) { | ||
e.message = `Unsuccessful response status code. ${e.message}`; | ||
} | ||
throw e; | ||
} | ||
}); | ||
} | ||
// tslint:disable-next-line no-any | ||
function instance(options) { | ||
@@ -124,2 +99,3 @@ return metadataAccessor('instance', options); | ||
exports.instance = instance; | ||
// tslint:disable-next-line no-any | ||
function project(options) { | ||
@@ -133,29 +109,18 @@ return metadataAccessor('project', options); | ||
function isAvailable() { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var err_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
// Attempt to read instance metadata. As configured, this will | ||
// retry 3 times if there is a valid response, and fail fast | ||
// if there is an ETIMEDOUT or ENOTFOUND error. | ||
return [4 /*yield*/, metadataAccessor('instance', undefined, 0)]; | ||
case 1: | ||
// Attempt to read instance metadata. As configured, this will | ||
// retry 3 times if there is a valid response, and fail fast | ||
// if there is an ETIMEDOUT or ENOTFOUND error. | ||
_a.sent(); | ||
return [2 /*return*/, true]; | ||
case 2: | ||
err_1 = _a.sent(); | ||
// Failure to resolve the metadata service means that it is not available. | ||
if (err_1.code && (err_1.code === 'ENOTFOUND' || err_1.code === 'ENOENT')) { | ||
return [2 /*return*/, false]; | ||
} | ||
// Throw unexpected errors. | ||
throw err_1; | ||
case 3: return [2 /*return*/]; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
// Attempt to read instance metadata. As configured, this will | ||
// retry 3 times if there is a valid response, and fail fast | ||
// if there is an ETIMEDOUT or ENOTFOUND error. | ||
yield metadataAccessor('instance', undefined, 0); | ||
return true; | ||
} | ||
catch (err) { | ||
// Failure to resolve the metadata service means that it is not available. | ||
if (err.code && (err.code === 'ENOTFOUND' || err.code === 'ENOENT')) { | ||
return false; | ||
} | ||
}); | ||
// Throw unexpected errors. | ||
throw err; | ||
} | ||
}); | ||
@@ -162,0 +127,0 @@ } |
{ | ||
"name": "gcp-metadata", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"description": "Get the metadata from a Google Cloud Platform environment", | ||
"repository": "stephenplusplus/gcp-metadata", | ||
"repository": "googleapis/gcp-metadata", | ||
"main": "./build/src/index.js", | ||
@@ -20,4 +20,8 @@ "types": "./build/src/index.d.ts", | ||
"test": "npm run test-only", | ||
"samples-test": "mocha samples/system-test", | ||
"system-test": "mocha build/system-test", | ||
"test-only": "nyc mocha build/test", | ||
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json" | ||
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json", | ||
"docs": "echo no docs 👻", | ||
"lint": "npm run check" | ||
}, | ||
@@ -37,7 +41,6 @@ "keywords": [ | ||
"axios": "^0.18.0", | ||
"extend": "^3.0.1", | ||
"json-bigint": "^0.3.0", | ||
"retry-axios": "0.3.2" | ||
}, | ||
"devDependencies": { | ||
"@types/extend": "^3.0.0", | ||
"@types/mocha": "^5.2.4", | ||
@@ -49,5 +52,5 @@ "@types/ncp": "^2.0.1", | ||
"@types/tmp": "0.0.33", | ||
"assert-rejects": "^0.1.1", | ||
"assert-rejects": "^1.0.0", | ||
"codecov": "^3.0.2", | ||
"gts": "^0.7.0", | ||
"gts": "^0.8.0", | ||
"hard-rejection": "^1.0.0", | ||
@@ -57,11 +60,11 @@ "mocha": "^5.2.0", | ||
"nock": "^9.2.6", | ||
"nyc": "^12.0.0", | ||
"pify": "^3.0.0", | ||
"nyc": "^13.0.0", | ||
"pify": "^4.0.0", | ||
"source-map-support": "^0.5.6", | ||
"tmp": "0.0.33", | ||
"typescript": "^2.8.3" | ||
"typescript": "^3.0.0" | ||
}, | ||
"engines": { | ||
"node": ">=4" | ||
"node": ">=6" | ||
} | ||
} |
@@ -22,4 +22,4 @@ # gcp-metadata | ||
```js | ||
const res = await gcpMetadata.instance(); | ||
console.log(res.data); // ... All metadata properties | ||
const data = await gcpMetadata.instance(); | ||
console.log(data); // ... All metadata properties | ||
``` | ||
@@ -29,4 +29,4 @@ | ||
```js | ||
const res = await gcpMetadata.instance('hostname'); | ||
console.log(res.data) // ...All metadata properties | ||
const data = await gcpMetadata.instance('hostname'); | ||
console.log(data) // ...Instance hostname | ||
``` | ||
@@ -36,9 +36,24 @@ | ||
```js | ||
const res = await gcpMetadata.instance({ | ||
const data = await gcpMetadata.instance({ | ||
property: 'tags', | ||
params: { alt: 'text' } | ||
}); | ||
console.log(res.data) // ...Tags as newline-delimited list | ||
console.log(data) // ...Tags as newline-delimited list | ||
``` | ||
### Take care with large number valued properties | ||
In some cases number valued properties returned by the Metadata Service may be | ||
too large to be representable as JavaScript numbers. In such cases we return | ||
those values as `BigNumber` objects (from the [bignumber.js][] library). Numbers | ||
that fit within the JavaScript number range will be returned as normal number | ||
values. | ||
```js | ||
const id = await gcpMetadata.instance('id'); | ||
console.log(id) // ... BigNumber { s: 1, e: 18, c: [ 45200, 31799277581759 ] } | ||
console.log(id.toString()) // ... 4520031799277581759 | ||
``` | ||
[bignumber.js]: https://github.com/MikeMcl/bignumber.js | ||
[circle]: https://circleci.com/gh/stephenplusplus/gcp-metadata | ||
@@ -45,0 +60,0 @@ [circleimg]: https://circleci.com/gh/stephenplusplus/gcp-metadata.svg?style=shield |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
16463
18
7
61
150
+ Addedjson-bigint@^0.3.0
+ Addedbignumber.js@9.1.2(transitive)
+ Addedjson-bigint@0.3.1(transitive)
- Removedextend@^3.0.1
- Removedextend@3.0.2(transitive)