UNPKG

@google-cloud/compute

Version:

Google Compute Engine Client Library for Node.js

1,596 lines (1,448 loc) 88.9 kB
/*! * Copyright 2015 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 arrify = require('arrify'); var common = require('@google-cloud/common'); var extend = require('extend'); var is = require('is'); var util = require('util'); var Firewall = require('./firewall.js'); var HealthCheck = require('./health-check.js'); var Network = require('./network.js'); var Operation = require('./operation.js'); var Project = require('./project.js'); var Region = require('./region.js'); var Rule = require('./rule.js'); var Service = require('./service.js'); var Snapshot = require('./snapshot.js'); var Zone = require('./zone.js'); /** * @typedef {object} ClientConfig * @property {string} [projectId] The project ID from the Google Developer's * Console, e.g. 'grape-spaceship-123'. We will also check the environment * variable `GCLOUD_PROJECT` for your project ID. If your app is running in * an environment which supports {@link https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application Application Default Credentials}, * your project ID will be detected automatically. * @property {string} [keyFilename] Full path to the a .json, .pem, or .p12 key * downloaded from the Google Developers Console. If you provide a path to a * JSON file, the `projectId` option above is not necessary. NOTE: .pem and * .p12 require you to specify the `email` option as well. * @property {string} [email] Account email address. Required when using a .pem * or .p12 keyFilename. * @property {object} [credentials] Credentials object. * @property {string} [credentials.client_email] * @property {string} [credentials.private_key] * @property {boolean} [autoRetry=true] Automatically retry requests if the * response is related to rate limits or certain intermittent server errors. * We will exponentially backoff subsequent requests by default. * @property {number} [maxRetries=3] Maximum number of automatic retries * attempted before returning the error. * @property {Constructor} [promise] Custom promise module to use instead of * native Promises. */ /** * @see [What is Google Compute Engine?]{@link https://cloud.google.com/compute/docs} * * @class * * @param {ClientConfig} [options] Configuration options. * * @example <caption>Create a client that uses Application Default Credentials (ADC)</caption> * const Compute = require('@google-cloud/compute'); * const compute = new Compute(); * * @example <caption>Create a client with explicit credentials</caption> * const Compute = require('@google-cloud/compute'); * const compute = new Compute({ * projectId: 'your-project-id', * keyFilename: '/path/to/keyfile.json' * }); */ function Compute(options) { if (!(this instanceof Compute)) { return new Compute(options); } options = common.util.normalizeArguments(this, options); var config = { baseUrl: 'https://www.googleapis.com/compute/v1', scopes: ['https://www.googleapis.com/auth/compute'], packageJson: require('../package.json'), }; common.Service.call(this, config, options); } util.inherits(Compute, common.Service); /** * Create a firewall. * * @see [Firewalls Overview]{@link https://cloud.google.com/compute/docs/networking#firewalls} * @see [Firewalls: insert API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/firewalls/insert} * * @throws {Error} if a name is not provided. * @throws {Error} if a config object is not provided. * * @param {string} name - Name of the firewall. * @param {object} config - See a * [Firewall resource](https://cloud.google.com/compute/docs/reference/v1/firewalls#resource). * @param {object} config.protocols - A map of protocol to port range. The keys * of the object refer to a protocol (e.g. `tcp`, `udp`) and the value for * the key are the ports/port-ranges that are allowed to make a connection. * If a `true` value, that means all ports on that protocol will be opened. * If `false`, all traffic on that protocol will be blocked. * @param {string[]} config.ranges - The IP address blocks that this rule * applies to, expressed in * [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) * format. * @param {string[]} config.tags - Instance tags which this rule applies to. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Firewall} callback.firewall - The created Firewall * object. * @param {Operation} callback.operation - An operation object * that can be used to check the status of the request. * @param {object} callback.apiResponse - The full API response. * * @example * var config = { * protocols: { * tcp: [3000], * udp: [] // An empty array means all ports are allowed. * }, * * ranges: ['0.0.0.0/0'] * }; * * function callback(err, firewall, operation, apiResponse) { * // `firewall` is a Firewall object. * * // `operation` is an Operation object that can be used to check the status * // of the request. * } * * gce.createFirewall('new-firewall-name', config, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.createFirewall('new-firewall-name', config).then(function(data) { * var firewall = data[0]; * var operation = data[1]; * var apiResponse = data[2]; * }); */ Compute.prototype.createFirewall = function(name, config, callback) { var self = this; if (!is.string(name)) { throw new Error('A firewall name must be provided.'); } if (!is.object(config)) { throw new Error('A firewall configuration object must be provided.'); } var body = extend({}, config, { name: name, }); if (body.protocols) { body.allowed = arrify(body.allowed); for (var protocol in body.protocols) { var allowedConfig = { IPProtocol: protocol, }; var ports = body.protocols[protocol]; if (ports === false || ports.length === 0) { continue; } // If the port is `true`, open up all ports on this protocol. allowedConfig.ports = ports === true ? [] : arrify(ports); body.allowed.push(allowedConfig); } delete body.protocols; } if (body.ranges) { body.sourceRanges = arrify(body.ranges); delete body.ranges; } if (body.tags) { body.sourceTags = arrify(body.tags); delete body.tags; } this.request( { method: 'POST', uri: '/global/firewalls', json: body, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var firewall = self.firewall(name); var operation = self.operation(resp.name); operation.metadata = resp; callback(null, firewall, operation, resp); } ); }; /** * Create an HTTP or HTTPS health check. * * @see [Health Checks Overview]{@link https://cloud.google.com/compute/docs/load-balancing/health-checks} * @see [HttpHealthCheck: insert API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/httpHealthChecks/insert} * @see [HttpsHealthCheck: insert API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/httpsHealthChecks/insert} * * @param {string} name - Name of the HTTP or HTTPS health check to create. * @param {object=} options - See a * [HttpHealthCheck resource](https://cloud.google.com/compute/docs/reference/v1/httpHealthChecks#resource) * and [HttpsHealthCheck resource](https://cloud.google.com/compute/docs/reference/v1/httpsHealthChecks#resource). * @param {boolean} options.https - Create an HTTPs health check. Default: * `false`. * @param {number} options.interval - How often (in seconds) to send a health * check. The default value is 5 seconds. (Alias for * `options.checkIntervalSec`) * @param {number} options.timeout - How long (in seconds) to wait before * claiming failure. The default value is 5 seconds. It is invalid for * this value to be greater than checkIntervalSec. (Alias for * `options.timeoutSec`) * @param {function=} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {HealthCheck} callback.healthCheck - The created * HealthCheck object. * @param {Operation} callback.operation - An operation object * that can be used to check the status of the request. * @param {object} callback.apiResponse - The full API response. * * @example * function callback(err, healthCheck, operation, apiResponse) { * // `healthCheck` is a HealthCheck object. * * // `operation` is an Operation object that can be used to check the status * // of network creation. * } * * gce.createHealthCheck('new-health-check-name', callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.createHealthCheck('new-health-check-name').then(function(data) { * var healthCheck = data[0]; * var operation = data[1]; * var apiResponse = data[2]; * }); */ Compute.prototype.createHealthCheck = function(name, options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } if (!is.string(name)) { throw new Error('A health check name must be provided.'); } var body = extend({}, options, { name: name, }); var https = options.https; delete body.https; if (body.interval) { body.checkIntervalSec = body.interval; delete body.interval; } if (body.timeout) { body.timeoutSec = body.timeout; delete body.timeout; } this.request( { method: 'POST', uri: '/global/' + (https ? 'httpsHealthChecks' : 'httpHealthChecks'), json: body, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var healthCheck = self.healthCheck(name, { https: https, }); var operation = self.operation(resp.name); operation.metadata = resp; callback(null, healthCheck, operation, resp); } ); }; /** * Create a network. * * @see [Networks Overview]{@link https://cloud.google.com/compute/docs/networking#networks} * @see [Networks: insert API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/networks/insert} * * @param {string} name - Name of the network. * @param {object} config - See a * [Network resource](https://cloud.google.com/compute/docs/reference/v1/networks#resource). * @param {string} config.gateway - A gateway address for default routing to * other networks. (Alias for `config.gatewayIPv4`) * @param {string} config.range - * [CIDR](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) range * of addresses that are legal on this network. (Alias for * `config.IPv4Range`) * @param {function=} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Network} callback.network - The created Network * object. * @param {Operation} callback.operation - An operation object * that can be used to check the status of the request. * @param {object} callback.apiResponse - The full API response. * * @example * var config = { * range: '10.240.0.0/16' * }; * * function callback(err, network, operation, apiResponse) { * // `network` is a Network object. * * // `operation` is an Operation object that can be used to check the status * // of network creation. * } * * gce.createNetwork('new-network', config, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.createNetwork('new-network', config).then(function(data) { * var network = data[0]; * var operation = data[1]; * var apiResponse = data[2]; * }); */ Compute.prototype.createNetwork = function(name, config, callback) { var self = this; var body = extend({}, config, { name: name, }); if (body.range) { body.IPv4Range = body.range; delete body.range; } if (body.gateway) { body.gatewayIPv4 = body.gateway; delete body.gateway; } this.request( { method: 'POST', uri: '/global/networks', json: body, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var network = self.network(name); var operation = self.operation(resp.name); operation.metadata = resp; callback(null, network, operation, resp); } ); }; /** * Create a global forwarding rule. * * @see [GlobalForwardingRule Resource]{@link https://cloud.google.com/compute/docs/reference/v1/globalForwardingRules#resource} * @see [GlobalForwardingRules: insert API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/globalForwardingRules/insert} * * @param {string} name - Name of the rule. * @param {object} config - See a * [GlobalForwardingRule resource](https://cloud.google.com/compute/docs/reference/v1/globalForwardingRules#resource). * @param {string=} config.ip - The single IP address this forwarding rule will * match against. All traffic that matches the IP address, protocol, and * ports of this forwarding rule will be handled by this rule. If specified, * the IP address must be a static external IP address. To create a new * ephemeral external IP address for the forwarding rule, leave this field * empty. (Alias for `config.IPAddress`) * @param {string=} config.protocol - The type of protocol that this forwarding * rule matches. Valid values are `AH`, `ESP`, `SCTP`, `TCP`, `UDP`. * Default: `TCP`. (Alias for `config.IPProtocol`) * @param {string=} config.range - A single port or single contiguous port * range, ranging from low to high for which this forwarding rule matches. * Packets of the specified protocol sent to these ports will be forwarded * on to the appropriate target pool or target instance. If this field is * left empty, then the forwarding matches traffic for all ports for the * specified protocol. (Alias for `config.portRange`) * @param {string} config.target - The full or valid partial URL of the target * resource to receive the matched traffic. This target must be a global * [`TargetHttpProxy` or `TargetHttpsProxy` resource](https://cloud.google.com/compute/docs/load-balancing/http/target-proxies). * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Rule} callback.rule - The created Rule object. * @param {Operation} callback.operation - An operation object * that can be used to check the status of the request. * @param {object} callback.apiResponse - The full API response. * * @example * var name = 'new-rule-name'; * * var config = { * target: 'global/targetHttpProxies/my-proxy', * range: '8080-8089' * }; * * gce.createRule(name, config, function (err, rule, operation, apiResponse) { * // `rule` is a Rule object. * * // `operation` is an Operation object that can be used to check the status * // of the request. * }); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.createRule(name, config).then(function(data) { * var rule = data[0]; * var operation = data[1]; * var apiResponse = data[2]; * }); */ Compute.prototype.createRule = function(name, config, callback) { var self = this; var body = extend({}, config, { name: name, }); if (body.ip) { body.IPAddress = body.ip; delete body.ip; } if (body.protocol) { body.IPProtocol = body.protocol; delete body.protocol; } if (body.range) { body.portRange = body.range; delete body.range; } this.request( { method: 'POST', uri: '/global/forwardingRules', json: body, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var rule = self.rule(name); var operation = self.operation(resp.name); operation.metadata = resp; callback(null, rule, operation, resp); } ); }; /** * Create a backend service. * * @see [Backend Services Overview]{@link https://cloud.google.com/compute/docs/load-balancing/http/backend-service} * @see [BackendServices: insert API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/backendServices/insert} * * @param {string} name - Name of the backend service. * @param {object} config - See a * [BackendService resource](https://cloud.google.com/compute/docs/reference/v1/backendServices#resource). * @param {function=} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Service} callback.service - The created Service * object. * @param {Operation} callback.operation - An operation object * that can be used to check the status of the request. * @param {object} callback.apiResponse - The full API response. * * @example * var config = { * backends: [ * { * group: 'URL of an Instance Group resource' * } * ], * healthChecks: [ * 'URL of an HTTP/HTTPS health check resource' * ] * }; * * function callback(err, service, operation, apiResponse) { * // `service` is a Service object. * * // `operation` is an Operation object that can be used to check the status * // of network creation. * } * * gce.createService('new-service', config, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.createService('new-service', config).then(function(data) { * var service = data[0]; * var operation = data[1]; * var apiResponse = data[2]; * }); */ Compute.prototype.createService = function(name, config, callback) { var self = this; var body = extend({}, config, { name: name, }); this.request( { method: 'POST', uri: '/global/backendServices', json: body, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var service = self.service(name); var operation = self.operation(resp.name); operation.metadata = resp; callback(null, service, operation, resp); } ); }; /** * Get a reference to a Google Compute Engine firewall. * * See {@link Network#firewall} to get a Firewall object for a specific * network. * * @see [Firewalls Overview]{@link https://cloud.google.com/compute/docs/networking#firewalls} * * @param {string} name - Name of the firewall. * @returns {Firewall} * * @example * var firewall = gce.firewall('firewall-name'); */ Compute.prototype.firewall = function(name) { return new Firewall(this, name); }; /** * Get a list of addresses. For a detailed description of method's options see * [API reference](https://goo.gl/r9XmXJ). * * @see [Instances and Networks]{@link https://cloud.google.com/compute/docs/instances-and-network} * @see [Addresses: aggregatedList API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/addresses/aggregatedList} * * @param {object=} options - Address search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of addresses to return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Address[]} callback.addresses - Address objects from * your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getAddresses(function(err, addresses) { * // addresses is an array of `Address` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, addresses, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getAddresses(nextQuery, callback); * } * } * * gce.getAddresses({ * autoPaginate: false * }, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.getAddresses().then(function(data) { * var addresses = data[0]; * }); */ Compute.prototype.getAddresses = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}; this.request( { uri: '/aggregated/addresses', qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var regions = resp.items || {}; var addresses = Object.keys(regions).reduce(function(acc, regionName) { var region = self.region(regionName.replace('regions/', '')); var regionAddresses = regions[regionName].addresses || []; regionAddresses.forEach(function(address) { var addressInstance = region.address(address.name); addressInstance.metadata = address; acc.push(addressInstance); }); return acc; }, []); callback(null, addresses, nextQuery, resp); } ); }; /** * Get a list of {@link Address} objects as a readable object stream. * * @param {object=} options - Configuration object. See * {@link Compute#getAddresses} for a complete list of options. * @returns {stream} * * @example * gce.getAddressesStream() * .on('error', console.error) * .on('data', function(address) { * // `address` is an `Address` object. * }) * .on('end', function() { * // All addresses retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getAddressesStream() * .on('data', function(address) { * this.end(); * }); */ Compute.prototype.getAddressesStream = common.paginator.streamify( 'getAddresses' ); /** * Get a list of autoscalers. For a detailed description of this method's * options, see the [API reference](https://cloud.google.com/compute/docs/reference/v1/autoscalers/aggregatedList). * * @see [Managing Autoscalers]{@link https://cloud.google.com/compute/docs/autoscaler/managing-autoscalers} * @see [Understanding Autoscaler Decisions]{@link https://cloud.google.com/compute/docs/autoscaler/understanding-autoscaler-decisions} * @see [Autoscalers: aggregatedList API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/autoscalers/aggregatedList} * * @param {object=} options - Address search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of addresses to return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Autoscaler[]} callback.autoscalers - Autoscaler * objects from your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getAutoscalers(function(err, autoscalers) { * // autoscalers is an array of `Autoscaler` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, autoscalers, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getAutoscalers(nextQuery, callback); * } * } * * gce.getAutoscalers({ * autoPaginate: false * }, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.getAutoscalers().then(function(data) { * var autoscalers = data[0]; * }); */ Compute.prototype.getAutoscalers = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}; this.request( { uri: '/aggregated/autoscalers', qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var zones = resp.items || {}; var autoscalers = Object.keys(zones).reduce(function(acc, zoneName) { if (zoneName.indexOf('zones/') !== 0) { return acc; } var zone = self.zone(zoneName.replace('zones/', '')); var zoneAutoscalers = zones[zoneName].autoscalers || []; zoneAutoscalers.forEach(function(autoscaler) { var autoscalerInstance = zone.autoscaler(autoscaler.name); autoscalerInstance.metadata = autoscaler; acc.push(autoscalerInstance); }); return acc; }, []); callback(null, autoscalers, nextQuery, resp); } ); }; /** * Get a list of {@link Autoscaler} objects as a readable object * stream. * * @param {object=} query - Configuration object. See * {@link Compute#getAutoscalers} for a complete list of options. * @returns {stream} * * @example * gce.getAutoscalersStream() * .on('error', console.error) * .on('data', function(autoscaler) { * // `autoscaler` is an `Autoscaler` object. * }) * .on('end', function() { * // All addresses retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getAutoscalersStream() * .on('data', function(address) { * this.end(); * }); */ Compute.prototype.getAutoscalersStream = common.paginator.streamify( 'getAutoscalers' ); /** * Get a list of disks. * * @see [Disks Overview]{@link https://cloud.google.com/compute/docs/disks} * @see [Disks: aggregatedList API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/disks/aggregatedList} * * @param {object=} options - Disk search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of disks to return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Disk[]} callback.disks - Disk objects from your * project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getDisks(function(err, disks) { * // `disks` is an array of `Disk` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, disks, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getDisks(nextQuery, callback); * } * } * * gce.getDisks({ * autoPaginate: false * }, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.getDisks().then(function(data) { * var disks = data[0]; * }); */ Compute.prototype.getDisks = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}; this.request( { uri: '/aggregated/disks', qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var zones = resp.items || {}; var disks = Object.keys(zones).reduce(function(acc, zoneName) { var zone = self.zone(zoneName.replace('zones/', '')); var disks = zones[zoneName].disks || []; disks.forEach(function(disk) { var diskInstance = zone.disk(disk.name); diskInstance.metadata = disk; acc.push(diskInstance); }); return acc; }, []); callback(null, disks, nextQuery, resp); } ); }; /** * Get a list of {@link Disk} objects as a readable object stream. * * @method Compute#getDisksStream * @param {object=} options - Configuration object. See * {@link Compute#getDisks} for a complete list of options. * @returns {stream} * * @example * gce.getDisksStream() * .on('error', console.error) * .on('data', function(disk) { * // `disk` is a `Disk` object. * }) * .on('end', function() { * // All disks retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getDisksStream() * .on('data', function(disk) { * this.end(); * }); */ Compute.prototype.getDisksStream = common.paginator.streamify('getDisks'); /** * Get a list of instance groups. * * @see [InstanceGroups Overview]{@link https://cloud.google.com/compute/docs/reference/v1/instanceGroups} * @see [InstanceGroups: aggregatedList API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/instanceGroups/aggregatedList} * * @param {object=} options - Instance group search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of instance groups to * return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {InstanceGroup[]} callback.instanceGroups - * InstanceGroup objects from your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getInstanceGroups(function(err, instanceGroups) { * // `instanceGroups` is an array of `InstanceGroup` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, instanceGroups, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getInstanceGroups(nextQuery, callback); * } * } * * gce.getInstanceGroups({ * autoPaginate: false * }, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.getInstanceGroups().then(function(data) { * var instanceGroups = data[0]; * }); */ Compute.prototype.getInstanceGroups = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}; this.request( { uri: '/aggregated/instanceGroups', qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var zones = resp.items || {}; var instanceGroups = Object.keys(zones).reduce(function(acc, zoneName) { var zone = self.zone(zoneName.replace('zones/', '')); var instanceGroups = zones[zoneName].instanceGroups || []; instanceGroups.forEach(function(group) { var instanceGroupInstance = zone.instanceGroup(group.name); instanceGroupInstance.metadata = group; acc.push(instanceGroupInstance); }); return acc; }, []); callback(null, instanceGroups, nextQuery, resp); } ); }; /** * Get a list of {@link InstanceGroup} objects as a readable object * stream. * * @method Compute#getInstanceGroupsStream * @param {object=} options - Configuration object. See * {@link Compute#getInstanceGroups} for a complete list of options. * @returns {stream} * * @example * gce.getInstanceGroupsStream() * .on('error', console.error) * .on('data', function(instanceGroup) { * // `instanceGroup` is an `InstanceGroup` object. * }) * .on('end', function() { * // All instance groups retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getInstanceGroupsStream() * .on('data', function(instanceGroup) { * this.end(); * }); */ Compute.prototype.getInstanceGroupsStream = common.paginator.streamify( 'getInstanceGroups' ); /** * Get a list of firewalls. * * @see [Firewalls Overview]{@link https://cloud.google.com/compute/docs/networking#firewalls} * @see [Firewalls: list API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/firewalls/list} * * @param {object=} options - Firewall search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of firewalls to return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Firewall[]} callback.firewalls - Firewall objects from * your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getFirewalls(function(err, firewalls) { * // `firewalls` is an array of `Firewall` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, firewalls, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getFirewalls(nextQuery, callback); * } * } * * gce.getFirewalls({ * autoPaginate: false * }, callback); * * gce.getFirewalls().then(function(data) { * var firewalls = data[0]; * }); */ Compute.prototype.getFirewalls = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}; this.request( { uri: '/global/firewalls', qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var firewalls = (resp.items || []).map(function(firewall) { var firewallInstance = self.firewall(firewall.name); firewallInstance.metadata = firewall; return firewallInstance; }); callback(null, firewalls, nextQuery, resp); } ); }; /** * Get a list of {@link Firewall} objects as a readable object stream. * * @method Compute#getFirewallsStream * @param {object=} query - Configuration object. See * {@link Compute#getFirewalls} for a complete list of options. * @returns {stream} * * @example * gce.getFirewallsStream() * .on('error', console.error) * .on('data', function(firewall) { * // `firewall` is a `Firewall` object. * }) * .on('end', function() { * // All firewalls retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getFirewallsStream() * .on('data', function(firewall) { * this.end(); * }); */ Compute.prototype.getFirewallsStream = common.paginator.streamify( 'getFirewalls' ); /** * Get a list of health checks. * * @see [Health Checks Overview]{@link https://cloud.google.com/compute/docs/load-balancing/health-checks} * @see [HttpHealthCheck: list API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/httpHealthChecks/list} * @see [HttpsHealthCheck: list API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/httpsHealthChecks/list} * * @param {object=} options - Health check search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {boolean} options.https - List only HTTPs health checks. Default: * `false`. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of networks to return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {HealthCheck[]} callback.healthChecks - HealthCheck * objects from your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getHealthChecks(function(err, healthChecks) { * // `healthChecks` is an array of `HealthCheck` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, healthChecks, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getHealthChecks(nextQuery, callback); * } * } * * gce.getHealthChecks({ * autoPaginate: false * }, callback); * * gce.getHealthChecks().then(function(data) { * var healthChecks = data[0]; * }); */ Compute.prototype.getHealthChecks = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = extend({}, options); var https = options.https; delete options.https; this.request( { uri: '/global/' + (https ? 'httpsHealthChecks' : 'httpHealthChecks'), qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var healthChecks = (resp.items || []).map(function(healthCheck) { var healthCheckInstance = self.healthCheck(healthCheck.name, { https: https, }); healthCheckInstance.metadata = healthCheck; return healthCheckInstance; }); callback(null, healthChecks, nextQuery, resp); } ); }; /** * Get a list of {@link HealthCheck} objects as a readable object * stream. * * @method Compute#getHealthChecksStream * @param {object=} options - Configuration object. See * {@link Compute#getHealthChecks} for a complete list of options. * @returns {stream} * * @example * gce.getHealthChecksStream() * .on('error', console.error) * .on('data', function(healthCheck) { * // `healthCheck` is a `HealthCheck` object. * }) * .on('end', function() { * // All health checks retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getHealthChecksStream() * .on('data', function(healthCheck) { * this.end(); * }); */ Compute.prototype.getHealthChecksStream = common.paginator.streamify( 'getHealthChecks' ); /** * Get a list of machine types in this project. * * @see [MachineTypes: list API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/machineTypes/aggregatedList} * @see [Machine Types Overview]{@link https://cloud.google.com/compute/docs/machine-types} * @see [MachineType Resource]{@link https://cloud.google.com/compute/docs/reference/v1/machineTypes} * * @param {object=} options - Machine type search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of machineTypes to * return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {MachineType[]} callback.machineTypes - MachineType * objects from your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getMachineTypes(function(err, machineTypes) { * // `machineTypes` is an array of `MachineType` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, machineTypes, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getMachineTypes(nextQuery, callback); * } * } * * gce.getMachineTypes({ * autoPaginate: false * }, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.getMachineTypes().then(function(data) { * var machineTypes = data[0]; * }); */ Compute.prototype.getMachineTypes = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}; this.request( { uri: '/aggregated/machineTypes', qs: options, }, function(err, resp) { if (err) { callback(err, null, null, resp); return; } var nextQuery = null; if (resp.nextPageToken) { nextQuery = extend({}, options, { pageToken: resp.nextPageToken, }); } var zones = resp.items || {}; var machineTypes = Object.keys(zones).reduce(function(acc, zoneName) { var zone = self.zone(zoneName.replace('zones/', '')); var machineTypesByZone = zones[zoneName].machineTypes || []; machineTypesByZone.forEach(function(machineType) { var machineTypeInstance = zone.machineType(machineType.name); machineTypeInstance.metadata = machineType; acc.push(machineTypeInstance); }); return acc; }, []); callback(null, machineTypes, nextQuery, resp); } ); }; /** * Get a list of {@link MachineType} objects in this project as a * readable object stream. * * @method Compute#getMachineTypesStream * @param {object=} options - Configuration object. See * {@link Compute#getMachineTypes} for a complete list of options. * @returns {stream} * * @example * gce.getMachineTypesStream() * .on('error', console.error) * .on('data', function(machineType) { * // `machineType` is a `MachineType` object. * }) * .on('end', function() { * // All machine types retrieved. * }); * * //- * // If you anticipate many results, you can end a stream early to prevent * // unnecessary processing and API requests. * //- * gce.getMachineTypesStream() * .on('data', function(machineType) { * this.end(); * }); */ Compute.prototype.getMachineTypesStream = common.paginator.streamify( 'getMachineTypes' ); /** * Get a list of networks. * * @see [Networks Overview]{@link https://cloud.google.com/compute/docs/networking#networks} * @see [Networks: list API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/networks/list} * * @param {object=} options - Network search options. * @param {boolean} options.autoPaginate - Have pagination handled * automatically. Default: true. * @param {string} options.filter - Search filter in the format of * `{name} {comparison} {filterString}`. * - **`name`**: the name of the field to compare * - **`comparison`**: the comparison operator, `eq` (equal) or `ne` * (not equal) * - **`filterString`**: the string to filter to. For string fields, this * can be a regular expression. * @param {number} options.maxApiCalls - Maximum number of API calls to make. * @param {number} options.maxResults - Maximum number of networks to return. * @param {string} options.pageToken - A previously-returned page token * representing part of the larger set of results to view. * @param {function} callback - The callback function. * @param {?error} callback.err - An error returned while making this request. * @param {Network[]} callback.networks - Network objects from * your project. * @param {object} callback.apiResponse - The full API response. * * @example * gce.getNetworks(function(err, networks) { * // `networks` is an array of `Network` objects. * }); * * //- * // To control how many API requests are made and page through the results * // manually, set `autoPaginate` to `false`. * //- * function callback(err, networks, nextQuery, apiResponse) { * if (nextQuery) { * // More results exist. * gce.getNetworks(nextQuery, callback); * } * } * * gce.getNetworks({ * autoPaginate: false * }, callback); * * //- * // If the callback is omitted, we'll return a Promise. * //- * gce.getNetworks().then(function(data) { * var networks = data[0]; * }); */ Compute.prototype.getNetworks = function(options, callback) { var self = this; if (is.fn(options)) { callback = options; options = {}; } options = options || {}