Skip to content

Commit d6d52c1

Browse files
authored
Merge pull request #1973 from muzzamilinovaqo/feature/plugin-aws-workspace-operational-state
aws workspace operational state
2 parents d2a6dbf + 9a1fab9 commit d6d52c1

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed

exports.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ module.exports = {
591591
'exportedFindingsEncrypted' : require(__dirname + '/plugins/aws/guardduty/exportedFindingsEncrypted.js'),
592592

593593
'workspacesVolumeEncryption' : require(__dirname + '/plugins/aws/workspaces/workspacesVolumeEncryption.js'),
594+
'workSpacesHealthyInstances' : require(__dirname + '/plugins/aws/workspaces/workSpacesHealthyInstances.js'),
594595
'workspacesIpAccessControl' : require(__dirname + '/plugins/aws/workspaces/workspacesIpAccessControl.js'),
595596
'unusedWorkspaces' : require(__dirname + '/plugins/aws/workspaces/unusedWorkspaces.js'),
596597
'workspacesInstanceCount' : require(__dirname + '/plugins/aws/workspaces/workspacesInstanceCount.js'),
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
var async = require('async');
2+
var helpers = require('../../../helpers/aws');
3+
4+
module.exports = {
5+
title: 'WorkSpaces Healthy Instances',
6+
category: 'WorkSpaces',
7+
domain: 'Identity and Access Management',
8+
severity: 'Medium',
9+
description: 'Ensures that the AWS WorkSpace have healthy instances.',
10+
more_info: 'Amazon WorkSpace should have healthy and running instances to ensure proper connection. The WorkSpace is marked as Unhealthy if response isn’t received from the WorkSpace in a timely manner. When the WorkSpaces instance’s status is unhealthy, it fails to respond to the HealthCheck requests.',
11+
recommended_action: 'Troubleshoot and resolve the unhealthy workspace issues.',
12+
link: 'https://docs.aws.amazon.com/workspaces/latest/adminguide/cloudwatch-dashboard.html',
13+
apis: ['WorkSpaces:describeWorkspaces','STS:getCallerIdentity'],
14+
realtime_triggers: ['workspaces:CreateWorkspaces','workspaces:DeleteWorkspaces'],
15+
16+
run: function(cache, settings, callback) {
17+
var results = [];
18+
var source = {};
19+
var regions = helpers.regions(settings);
20+
var acctRegion = helpers.defaultRegion(settings);
21+
var awsOrGov = helpers.defaultPartition(settings);
22+
23+
var accountId = helpers.addSource(cache, source, ['sts', 'getCallerIdentity', acctRegion, 'data']);
24+
25+
async.each(regions.workspaces, function(region, rcb){
26+
var listWorkspaces = helpers.addSource(cache, source, ['workspaces', 'describeWorkspaces', region]);
27+
28+
if (!listWorkspaces) return rcb();
29+
30+
if (!listWorkspaces || listWorkspaces.err || !listWorkspaces.data) {
31+
helpers.addResult(results, 3,
32+
'Unable to list Workspaces: ' + helpers.addError(listWorkspaces), region);
33+
return rcb();
34+
}
35+
36+
if (!listWorkspaces.data.length) {
37+
helpers.addResult(results, 0,
38+
'No WorkSpaces instances found', region);
39+
return rcb();
40+
}
41+
listWorkspaces.data.forEach(workspace => {
42+
if (!workspace.WorkspaceId) return;
43+
44+
let resource = `arn:${awsOrGov}:region:${region}:${accountId}:worskpace/${workspace.WorkspaceId}`;
45+
46+
if (workspace.State === 'UNHEALTHY') {
47+
helpers.addResult(results, 2,
48+
'Workspace instance is not in healthy state', region, resource);
49+
} else {
50+
helpers.addResult(results, 0,
51+
'WorkSpace instance is in healthy state', region, resource);
52+
}
53+
});
54+
55+
rcb();
56+
}, function() {
57+
callback(null, results, source);
58+
});
59+
}
60+
};
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
var expect = require('chai').expect;
3+
var workSpacesHealthyInstances = require('./workSpacesHealthyInstances');
4+
5+
const describeWorkspaces = [
6+
{
7+
WorkspaceId: 'ws-f7hsrphp6',
8+
DirectoryId: 'd-9067552532',
9+
UserName: 'test',
10+
IpAddress: '172.16.1.134',
11+
State: 'AVAILABLE',
12+
BundleId: 'wsb-clj85qzj1',
13+
SubnetId: 'subnet-017fd5eda595ac73f',
14+
ModificationStates: []
15+
},
16+
{
17+
WorkspaceId: 'ws-f7hsrphp6',
18+
DirectoryId: 'd-9067552532',
19+
UserName: 'test',
20+
IpAddress: '172.16.1.134',
21+
State: 'UNHEALTHY',
22+
BundleId: 'wsb-clj85qzj1',
23+
ModificationStates: []
24+
},
25+
];
26+
27+
const createCache = (data, err) => {
28+
return {
29+
workspaces: {
30+
describeWorkspaces: {
31+
'us-east-1': {
32+
data: data,
33+
err: err
34+
}
35+
}
36+
}
37+
};
38+
};
39+
40+
const createErrorCache = () => {
41+
return {
42+
workspaces: {
43+
describeWorkspaces: {
44+
'us-east-1': {
45+
data: [],
46+
err: {
47+
message: 'error describing workspaces'
48+
},
49+
}
50+
}
51+
}
52+
};
53+
};
54+
55+
describe('workSpacesHealthyInstances', function () {
56+
describe('run', function () {
57+
it('should PASS if no workspace instances found', function (done) {
58+
const cache = createCache([]);
59+
workSpacesHealthyInstances.run(cache, { }, (err, results) => {
60+
expect(results.length).to.equal(1);
61+
expect(results[0].status).to.equal(0);
62+
expect(results[0].region).to.include('us-east-1')
63+
expect(results[0].message).to.include('No WorkSpaces instances found')
64+
done();
65+
});
66+
});
67+
68+
it('should UNKNOWN if Unable to query for WorkSpaces instances', function (done) {
69+
const cache = createErrorCache();
70+
workSpacesHealthyInstances.run(cache,{}, (err, results) => {
71+
expect(results.length).to.equal(1);
72+
expect(results[0].status).to.equal(3);
73+
expect(results[0].region).to.include('us-east-1')
74+
expect(results[0].message).to.include('Unable to list Workspaces')
75+
done();
76+
});
77+
});
78+
79+
it('should PASS if the Workspace is operational', function (done) {
80+
const cache = createCache([describeWorkspaces[0]]);
81+
workSpacesHealthyInstances.run(cache, { }, (err, results) => {
82+
expect(results.length).to.equal(1);
83+
expect(results[0].status).to.equal(0);
84+
expect(results[0].region).to.equal('us-east-1');
85+
expect(results[0].message).to.include('WorkSpace instance is in healthy state')
86+
done();
87+
});
88+
});
89+
90+
it('should FAIL if Workspace is not operational', function (done) {
91+
const cache = createCache([describeWorkspaces[1]]);
92+
workSpacesHealthyInstances.run(cache, { }, (err, results) => {
93+
expect(results.length).to.equal(1);
94+
expect(results[0].status).to.equal(2);
95+
expect(results[0].region).to.equal('us-east-1')
96+
expect(results[0].message).to.include('Workspace instance is not in healthy state')
97+
done();
98+
});
99+
});
100+
});
101+
});

0 commit comments

Comments
 (0)