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

Adds getManagedInstances and deleteInstances to InstanceGroupManger API #265

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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