Skip to content

Commit

Permalink
SAAS-2470: Google Compute Engine Instance Preemptibility Disabled (aq…
Browse files Browse the repository at this point in the history
…uasecurity#873)

* Google Compute Engine Instance Preemptibility Disabled

* renamed files

Co-authored-by: AkhtarAmir <[email protected]>
  • Loading branch information
mehakseedat63 and AkhtarAmir authored Sep 30, 2021
1 parent 0e2a5d1 commit e566913
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ module.exports = {
'instanceDesiredMachineTypes' : require(__dirname + '/plugins/google/compute/instanceDesiredMachineTypes.js'),
'automaticRestartEnabled' : require(__dirname + '/plugins/google/compute/automaticRestartEnabled.js'),
'instanceTemplateMachineTypes' : require(__dirname + '/plugins/google/compute/instanceTemplateMachineTypes.js'),
'instancePreemptibility' : require(__dirname + '/plugins/google/compute/instancePreemptibility.js'),
'diskInUse' : require(__dirname + '/plugins/google/compute/diskInUse.js'),
'osLogin2FAEnabled' : require(__dirname + '/plugins/google/compute/osLogin2FAEnabled.js'),
'diskAutomaticBackupEnabled' : require(__dirname + '/plugins/google/compute/diskAutomaticBackupEnabled.js'),
Expand Down
68 changes: 68 additions & 0 deletions plugins/google/compute/instancePreemptibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
var async = require('async');
var helpers = require('../../../helpers/google');

module.exports = {
title: 'Instance Preemptibility Disabled',
category: 'Compute',
description: 'Ensure that preemptible Virtual Machine instances do not exist.',
more_info: 'Preemptible instances are excess Compute Engine capacity, so their availability varies with usage. Compute Engine can terminate preemptible instances if it requires access to these resources for other tasks.',
link: 'https://cloud.google.com/compute/docs/instances/preemptible',
recommended_action: 'Ensure that your Google Compute Engine VM instances are not preemptible.',
apis: ['instances:compute:list', 'projects:get'],

run: function(cache, settings, callback) {
var results = [];
var source = {};
var regions = helpers.regions();

let projects = helpers.addSource(cache, source,
['projects','get', 'global']);

if (!projects || projects.err || !projects.data || !projects.data.length) {
helpers.addResult(results, 3,
'Unable to query for projects: ' + helpers.addError(projects), 'global', null, null, (projects) ? projects.err : null);
return callback(null, results, source);
}

var project = projects.data[0].name;
async.each(regions.instances.compute, (region, rcb) => {
var noInstances = [];
var zones = regions.zones;
async.each(zones[region], function(zone, zcb) {
var instances = helpers.addSource(cache, source,
['instances', 'compute','list', zone ]);

if (!instances) return zcb();

if (instances.err || !instances.data) {
helpers.addResult(results, 3, 'Unable to query compute instances', region, null, null, instances.err);
return zcb();
}

if (!instances.data.length) {
noInstances.push(zone);
return zcb();
}

instances.data.forEach(instance => {
let resource = helpers.createResourceName('instances', instance.name, project, 'zone', zone);
if (instance.scheduling && instance.scheduling.preemptible) {
helpers.addResult(results, 2,
'VM Instance is preemptible', region, resource);
} else {
helpers.addResult(results, 0,
'VM Instance is not preemptible', region, resource);
}
});
zcb();
}, function() {
if (noInstances.length) {
helpers.addResult(results, 0, `No instances found in following zones: ${noInstances.join(', ')}`, region);
}
rcb();
});
}, function() {
callback(null, results, source);
});
}
};
140 changes: 140 additions & 0 deletions plugins/google/compute/instancePreemptibility.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
var assert = require('assert');
var expect = require('chai').expect;
var plugin = require('./instancePreemptibility');

const createCache = (instanceData, error) => {
return {
instances: {
compute: {
list: {
'us-central1-a': {
data: instanceData,
err: error
}
}
}
},
projects: {
get: {
'global': {
data: 'tets-proj'
}
}
}
}
};

describe('instancePreemptibility', function () {
describe('run', function () {

it('should give unknown if an instance error occurs', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query compute instances');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[],
['error']
);

plugin.run(cache, {}, callback);
});

it('should pass no VM Instances', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No instances found');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[],
null
);

plugin.run(cache, {}, callback);
});

it('should fail if VM instance is preemptible', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('VM Instance is preemptible');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[
{
"kind": "compute#instance",
"id": "53523",
"creationTimestamp": "2019-10-04T13:44:44.117-07:00",
"name": "instance-3",
"description": "",
"tags": {
"fingerprint": "42WmSpB8rSM="
},
"machineType": "https://www.googleapis.com/compute/v1/projects/rosy-booth-253119/zones/us-central1-a/machineTypes/n1-standard-1",
"status": "RUNNING",
"zone": "https://www.googleapis.com/compute/v1/projects/rosy-booth-253119/zones/us-central1-a",
"canIpForward": true,
"selfLink": "https://www.googleapis.com/compute/v1/projects/rosy-booth-253119/zones/us-central1-a/instances/instance-3",
"scheduling": {
"onHostMaintenance": "MIGRATE",
"automaticRestart": false,
"preemptible": true
}
}
],
null
);

plugin.run(cache, {}, callback);
})

it('should pass if VM instance is not preemptible', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.equal('VM Instance is not preemptible');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[
{
"kind": "compute#instance",
"id": "45444",
"creationTimestamp": "2019-09-25T14:05:30.014-07:00",
"name": "instance-2",
"description": "",
"tags": {
"fingerprint": "42WmSpB8rSM="
},
"machineType": "https://www.googleapis.com/compute/v1/projects/rosy-booth-253119/zones/us-central1-a/machineTypes/g1-small",
"status": "RUNNING",
"zone": "https://www.googleapis.com/compute/v1/projects/rosy-booth-253119/zones/us-central1-a",
"canIpForward": false,
"selfLink": "https://www.googleapis.com/compute/v1/projects/rosy-booth-253119/zones/us-central1-a/instances/instance-2",
"scheduling": {
"onHostMaintenance": "MIGRATE",
"automaticRestart": true,
"preemptible": false
}
}
]
);

plugin.run(cache, {}, callback);
})

})
});

0 comments on commit e566913

Please sign in to comment.