Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
feat: Add getManagedInstances and deleteInstances to InstanceGroupMan…
Browse files Browse the repository at this point in the history
…ger API (#265)

* Adds getManagedInstances and deleteInstances to InstanceGroupManger API
* Fixes a broken documentation link
  • Loading branch information
Alan K authored and stephenplusplus committed Feb 11, 2019
1 parent 02223bc commit 81921d9
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 2 deletions.
151 changes: 150 additions & 1 deletion src/instance-group-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

'use strict';

const arrify = require('arrify');
const common = require('@google-cloud/common');
const is = require('is');
const {promisifyAll} = require('@google-cloud/promisify');
const {teenyRequest} = require('teeny-request');

Expand Down Expand Up @@ -153,7 +155,154 @@ class InstanceGroupManager extends common.ServiceObject {
*/
this.name = name;
}

/**
* Flags the specified instances in the managed instance group for immediate deletion.
* @see [InstanceGroupManagers: deleteInstances API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/instanceGroupManagers/deleteInstances}
* @param {VM|VM[]} vms - VM instances to delete from
* this instance group manager.
* @param {function} callback - The callback function.
* @param {?error} callback.err - An error returned while making this request.
* @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
* const Compute = require('@google-cloud/compute');
* const compute = new Compute();
* const zone = compute.zone('us-central1-a');
* const instanceGroupManager = zone.instanceGroupManager('web-servers');
*
* const vms = [
* gce.zone('us-central1-a').vm('http-server'),
* gce.zone('us-central1-a').vm('https-server')
* ];
*
* instanceGroupManager.deleteInstances(vms, function(err, operation, apiResponse) {
* // `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.
* //-
* instanceGroupManager.deleteInstances(vms).then(function(data) {
* const operation = data[0];
* const apiResponse = data[1];
* });
*/
deleteInstances(vms, callback) {
const self = this;
this.request(
{
method: 'POST',
uri: '/deleteInstances',
json: {
instances: arrify(vms).map(function(vm) {
return vm.url;
}),
},
},
function(err, resp) {
if (err) {
callback(err, null, resp);
return;
}
const operation = self.zone.operation(resp.name);
operation.metadata = resp;
callback(null, operation, resp);
}
);
}
/**
* Get a list of managed VM instances in this instance group manager.
*
* @see [InstanceGroupManagers: listManagedInstances API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/instanceGroupManagers/listManagedInstances}
*
* @param {object=} options - Instance 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 VMs 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 {VM[]} callback.vms - VM objects from this instance
* group.
* @param {object} callback.apiResponse - The full API response.
*
* @example
* const Compute = require('@google-cloud/compute');
* const compute = new Compute();
* const zone = compute.zone('us-central1-a');
* const instanceGroupManager = zone.instanceGroupManager('web-servers');
*
* instanceGroupManager.getManagedInstances(function(err, vms) {
* // `vms` is an array of `VM` objects.
* });
*
* //-
* // To control how many API requests are made and page through the results
* // manually, set `autoPaginate` to `false`.
* //-
* function callback(err, vms, nextQuery, apiResponse) {
* if (nextQuery) {
* // More results exist.
* instanceGroupManager.getManagedInstances(nextQuery, callback);
* }
* }
*
* instanceGroupManager.getManagedInstances({
* autoPaginate: false
* }, callback);
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* instanceGroupManager.getManagedInstances().then(function(data) {
* const vms = data[0];
* });
*/
getManagedInstances(options, callback) {
const self = this;
if (is.fn(options)) {
callback = options;
options = {};
}
options = options || {};
this.request(
{
method: 'POST',
uri: '/listManagedInstances',
qs: options,
},
function(err, resp) {
if (err) {
callback(err, null, null, resp);
return;
}
let nextQuery = null;
if (resp.nextPageToken) {
nextQuery = Object.assign({}, options, {
pageToken: resp.nextPageToken,
});
}
const vms = arrify(resp.managedInstances).map(function(vm) {
const vmInstance = self.zone.vm(vm.instance);
vmInstance.metadata = vm;
return vmInstance;
});
callback(null, vms, nextQuery, resp);
}
);
}
/**
* Resizes the managed instance group.
*
Expand Down
2 changes: 1 addition & 1 deletion src/instance-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ class InstanceGroup extends common.ServiceObject {
/**
* Get a list of VM instances in this instance group.
*
* @see [InstaceGroups: listInstances API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/instanceGroups/listInstances}
* @see [InstanceGroups: listInstances API Documentation]{@link https://cloud.google.com/compute/docs/reference/v1/instanceGroups/listInstances}
*
* @param {object=} options - Instance search options.
* @param {boolean} options.autoPaginate - Have pagination handled
Expand Down
193 changes: 193 additions & 0 deletions test/instance-group-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,199 @@ describe('InstanceGroupManager', function() {
});
});

describe('deleteInstances', function() {
const VMS = [{url: 'vm-url'}, {url: 'vm-url-2'}];

it('should make the correct API request', function(done) {
instanceGroupManager.request = function(reqOpts) {
assert.strictEqual(reqOpts.method, 'POST');
assert.strictEqual(reqOpts.uri, '/deleteInstances');
assert.deepStrictEqual(reqOpts.json, {
instances: VMS.map(function(vm) {
return vm.url;
}),
});

done();
};

instanceGroupManager.deleteInstances(VMS, assert.ifError);
});

describe('error', function() {
const apiResponse = {};
const error = new Error('Error.');

beforeEach(function() {
instanceGroupManager.request = function(reqOpts, callback) {
callback(error, apiResponse);
};
});

it('should return an error and API response', function(done) {
instanceGroupManager.deleteInstances(VMS, function(
err,
operation,
apiResponse_
) {
assert.strictEqual(err, error);
assert.strictEqual(operation, null);
assert.strictEqual(apiResponse_, apiResponse);
done();
});
});
});

describe('success', function() {
const apiResponse = {name: 'op-name'};

beforeEach(function() {
instanceGroupManager.request = function(reqOpts, callback) {
callback(null, apiResponse);
};
});

it('should return an Operation and API response', function(done) {
const operation = {};

instanceGroupManager.zone.operation = function(name) {
assert.strictEqual(name, apiResponse.name);
return operation;
};

instanceGroupManager.deleteInstances(VMS, function(
err,
operation_,
apiResponse_
) {
assert.ifError(err);
assert.strictEqual(operation_, operation);
assert.strictEqual(operation.metadata, apiResponse);
assert.strictEqual(apiResponse_, apiResponse);
done();
});
});
});
});

describe('getManagedInstances', function() {
beforeEach(function() {
instanceGroupManager.zone.vm = function() {
return {};
};
});

it('should accept only a callback', function(done) {
instanceGroupManager.request = function(reqOpts) {
assert.deepStrictEqual(reqOpts.qs, {});
done();
};

instanceGroupManager.getManagedInstances(assert.ifError);
});

it('should make the correct API request', function(done) {
const query = {a: 'b', c: 'd'};

instanceGroupManager.request = function(reqOpts) {
assert.strictEqual(reqOpts.uri, '/listManagedInstances');
assert.strictEqual(reqOpts.qs, query);

done();
};

instanceGroupManager.getManagedInstances(query, assert.ifError);
});

describe('error', function() {
const error = new Error('Error.');
const apiResponse = {a: 'b', c: 'd'};

beforeEach(function() {
instanceGroupManager.request = function(reqOpts, callback) {
callback(error, apiResponse);
};
});

it('should execute callback with error & API response', function(done) {
instanceGroupManager.getManagedInstances({}, function(
err,
vms,
nextQuery,
apiResponse_
) {
assert.strictEqual(err, error);
assert.strictEqual(nextQuery, null);
assert.strictEqual(apiResponse_, apiResponse);
done();
});
});
});

describe('success', function() {
const apiResponse = {
managedInstances: [{instance: 'vm-name'}],
};

beforeEach(function() {
instanceGroupManager.request = function(reqOpts, callback) {
callback(null, apiResponse);
};
});

it('should build a nextQuery if necessary', function(done) {
const nextPageToken = 'next-page-token';
const apiResponseWithNextPageToken = Object.assign({}, apiResponse, {
nextPageToken: nextPageToken,
});
const expectedNextQuery = {
pageToken: nextPageToken,
};

instanceGroupManager.request = function(reqOpts, callback) {
callback(null, apiResponseWithNextPageToken);
};

instanceGroupManager.getManagedInstances({}, function(
err,
vms,
nextQuery
) {
assert.ifError(err);

assert.deepStrictEqual(nextQuery, expectedNextQuery);

done();
});
});

it('should execute callback with VMs & API response', function(done) {
const vm = {};

instanceGroupManager.zone.vm = function(name) {
assert.strictEqual(name, apiResponse.managedInstances[0].instance);
return vm;
};

instanceGroupManager.getManagedInstances({}, function(
err,
vms,
nextQuery,
apiResponse_
) {
assert.ifError(err);

assert.strictEqual(vms[0], vm);
assert.strictEqual(vms[0].metadata, apiResponse.managedInstances[0]);

assert.strictEqual(apiResponse_, apiResponse);

done();
});
});
});
});

describe('resize', function() {
const query = {size: 1};

Expand Down

0 comments on commit 81921d9

Please sign in to comment.