Skip to content

Commit 4c5a7a3

Browse files
authored
Merge pull request #1682 from abdullahaslam306/feature/SAAS-18217-azure-acr-log-analytics-enabled
Feature/saas 18217 azure acr log analytics enabled
2 parents 1042122 + e842d08 commit 4c5a7a3

File tree

4 files changed

+222
-0
lines changed

4 files changed

+222
-0
lines changed

exports.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ module.exports = {
906906
'acrHasTags' : require(__dirname + '/plugins/azure/containerregistry/acrHasTags.js'),
907907
'acrPublicAccess' : require(__dirname + '/plugins/azure/containerregistry/acrPublicAccess.js'),
908908
'acrCMKEncryption' : require(__dirname + '/plugins/azure/containerregistry/acrCMKEncryption.js'),
909+
'acrLogAnalyticsEnabled' : require(__dirname + '/plugins/azure/containerregistry/acrLogAnalyticsEnabled.js'),
909910
'acrAnonymousPullAccessEnabled' : require(__dirname + '/plugins/azure/containerregistry/acrAnonymousPullAccessEnabled.js'),
910911

911912
'endpointLoggingEnabled' : require(__dirname + '/plugins/azure/cdnprofiles/endpointLoggingEnabled.js'),

helpers/azure/api.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,11 @@ var tertiarycalls = {
899899
reliesOnPath: 'networkSecurityGroups.listAll',
900900
properties: ['id'],
901901
url: 'https://management.azure.com/{id}/providers/microsoft.insights/diagnosticSettings?api-version=2017-05-01-preview'
902+
},
903+
listByContainerRegistries: {
904+
reliesOnPath: 'registries.list',
905+
properties: ['id'],
906+
url: 'https://management.azure.com/{id}/providers/microsoft.insights/diagnosticSettings?api-version=2021-05-01-preview'
902907
}
903908
},
904909
backupShortTermRetentionPolicies: {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const async = require('async');
2+
const helpers = require('../../../helpers/azure');
3+
4+
module.exports = {
5+
title: 'ACR Log Analytics Enabled',
6+
category: 'Container Registry',
7+
domain: 'Containers',
8+
description: 'Ensure that Azure container registry logs are sent to the Log Analytics workspace.',
9+
more_info: 'Enabling Log Analytics for Azure container registry ensures that logs are shipped to a central repository that can be queried and audited.',
10+
recommended_action: 'Modify container registry and enable Send to Log Analytics from diagnostic settings.',
11+
link: 'https://learn.microsoft.com/en-us/azure/container-registry/monitor-service',
12+
apis: ['registries:list', 'diagnosticSettings:listByContainerRegistries'],
13+
14+
run: function(cache, settings, callback) {
15+
const results = [];
16+
const source = {};
17+
const locations = helpers.locations(settings.govcloud);
18+
19+
async.each(locations.registries, (location, rcb) => {
20+
const registries = helpers.addSource(cache, source,
21+
['registries', 'list', location]);
22+
23+
if (!registries) return rcb();
24+
25+
if (registries.err || !registries.data) {
26+
helpers.addResult(results, 3,
27+
'Unable to query for container registries: ' + helpers.addError(registries), location);
28+
return rcb();
29+
}
30+
31+
if (!registries.data.length) {
32+
helpers.addResult(results, 0, 'No existing container registries found', location);
33+
return rcb();
34+
}
35+
36+
for (let registry of registries.data) {
37+
const diagnosticSettings = helpers.addSource(cache, source,
38+
['diagnosticSettings', 'listByContainerRegistries', location, registry.id]);
39+
40+
if (!diagnosticSettings || diagnosticSettings.err || !diagnosticSettings.data) {
41+
helpers.addResult(results, 3,
42+
'Unable to query diagnostics settings: ' + helpers.addError(diagnosticSettings), location, registry.id);
43+
} else if (!diagnosticSettings.data.length) {
44+
helpers.addResult(results, 2, 'No existing diagnostics settings', location, registry.id);
45+
} else {
46+
let found = diagnosticSettings.data.find(ds => ds.logs && ds.logs.length);
47+
48+
if (found) {
49+
helpers.addResult(results, 0, 'Logging is enabled for container registry', location, registry.id);
50+
} else {
51+
helpers.addResult(results, 2, 'Logging is not enabled for container registry', location, registry.id);
52+
}
53+
}
54+
}
55+
56+
rcb();
57+
}, function() {
58+
callback(null, results, source);
59+
});
60+
}
61+
};
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
var expect = require('chai').expect;
2+
var acrLogAnalyticsEnabled = require('./acrLogAnalyticsEnabled');
3+
4+
const containerRegistries = [
5+
{
6+
"id": "/subscriptions/ade0e01e-f9cd-49d3-bba7-d5a5362a3414/resourceGroups/devresourcegroup/providers/Microsoft.ContainerRegistry/registries/testregistry12543",
7+
"name": "testregistry12543",
8+
"type": "Microsoft.ContainerRegistry/registries",
9+
"location": "eastus",
10+
"tags": {},
11+
"sku": {
12+
"name": "Basic",
13+
"tier": "Basic"
14+
},
15+
"loginServer": "testregistry12543.azurecr.io",
16+
"creationDate": "2019-10-18T21:16:01.347Z",
17+
"provisioningState": "Succeeded",
18+
"adminUserEnabled": true,
19+
"publicNetworkAccess": "Enabled"
20+
}
21+
];
22+
23+
const diagnosticSettings = [
24+
{
25+
id: '/subscriptions/dce7d0ad-ebf6-437f-a3b0-28fc0d22117e/resourcegroups/devresourcegroup/providers/Microsoft.ContainerRegistry/registries/gio-test-events-1-nsg/providers/microsoft.insights/diagnosticSettings/gio-test-setting',
26+
type: 'Microsoft.Insights/diagnosticSettings',
27+
name: 'gio-test-setting',
28+
location: 'eastus',
29+
kind: null,
30+
tags: null,
31+
identity: null,
32+
storageAccountId: null,
33+
serviceBusRuleId: null,
34+
workspaceId: '/subscriptions/dce7d0ad-ebf6-437f-a3b0-28fc0d22117e/resourcegroups/defaultresourcegroup-eus/providers/microsoft.operationalinsights/workspaces/defaultworkspace-dce7d0ad-ebf6-437f-a3b0-28fc0d22117e-eus',
35+
eventHubAuthorizationRuleId: null,
36+
eventHubName: null,
37+
metrics: [],
38+
logs: [
39+
{
40+
category: 'NetworkSecurityGroupEvent',
41+
categoryGroup: null,
42+
enabled: true,
43+
retentionPolicy: [Object]
44+
},
45+
{
46+
category: 'NetworkSecurityGroupRuleCounter',
47+
categoryGroup: null,
48+
enabled: true,
49+
retentionPolicy: [Object]
50+
}
51+
],
52+
logAnalyticsDestinationType: null
53+
},
54+
{
55+
id: '/subscriptions/dce7d0ad-ebf6-437f-a3b0-28fc0d22117e/resourcegroups/deleteasap/providers/microsoft.network/networksecuritygroups/gio-test-events-1-nsg/providers/microsoft.insights/diagnosticSettings/gio-test-setting',
56+
type: 'Microsoft.Insights/diagnosticSettings',
57+
name: 'gio-test-setting',
58+
location: 'eastus',
59+
kind: null,
60+
tags: null,
61+
identity: null,
62+
storageAccountId: null,
63+
serviceBusRuleId: null,
64+
workspaceId: '/subscriptions/dce7d0ad-ebf6-437f-a3b0-28fc0d22117e/resourcegroups/defaultresourcegroup-eus/providers/microsoft.operationalinsights/workspaces/defaultworkspace-dce7d0ad-ebf6-437f-a3b0-28fc0d22117e-eus',
65+
eventHubAuthorizationRuleId: null,
66+
eventHubName: null,
67+
metrics: [],
68+
logs: [],
69+
logAnalyticsDestinationType: null
70+
}
71+
];
72+
73+
74+
const createCache = (listRegistries, diagnosticSetting) => {
75+
let logs = {};
76+
if (listRegistries && listRegistries.length > 0) {
77+
logs[listRegistries[0].id] = {
78+
data: diagnosticSetting
79+
};
80+
}
81+
82+
return {
83+
registries: {
84+
list: {
85+
'eastus': {
86+
data: listRegistries
87+
}
88+
}
89+
},
90+
diagnosticSettings: {
91+
listByContainerRegistries: {
92+
'eastus': logs
93+
}
94+
}
95+
};
96+
};
97+
98+
describe('acrLogAnalyticsEnabled', function() {
99+
describe('run', function() {
100+
it('should give passing result if No existing container registry found', function(done) {
101+
const cache = createCache([], []);
102+
acrLogAnalyticsEnabled.run(cache, {}, (err, results) => {
103+
expect(results.length).to.equal(1);
104+
expect(results[0].status).to.equal(0);
105+
expect(results[0].message).to.include('No existing container registries found');
106+
expect(results[0].region).to.equal('eastus');
107+
done();
108+
});
109+
});
110+
111+
it('should give Failing result if No existing diagnostics settings', function(done) {
112+
const cache = createCache([containerRegistries[0]],[]);
113+
acrLogAnalyticsEnabled.run(cache, {}, (err, results) => {
114+
expect(results.length).to.equal(1);
115+
expect(results[0].status).to.equal(2);
116+
expect(results[0].message).to.include('No existing diagnostics settings');
117+
expect(results[0].region).to.equal('eastus');
118+
done();
119+
});
120+
});
121+
122+
it('should give unknown result if Unable to query for container registry Groups', function(done) {
123+
const cache = createCache(null);
124+
acrLogAnalyticsEnabled.run(cache, {}, (err, results) => {
125+
expect(results.length).to.equal(1);
126+
expect(results[0].status).to.equal(3);
127+
expect(results[0].message).to.include('Unable to query for container registries:');
128+
expect(results[0].region).to.equal('eastus');
129+
done();
130+
});
131+
});
132+
133+
it('should give passing result if Log Analytics is enabled for ACR', function(done) {
134+
const cache = createCache([containerRegistries[0]], [diagnosticSettings[0]]);
135+
acrLogAnalyticsEnabled.run(cache, {}, (err, results) => {
136+
expect(results.length).to.equal(1);
137+
expect(results[0].status).to.equal(0);
138+
expect(results[0].message).to.include('Logging is enabled for container registry');
139+
expect(results[0].region).to.equal('eastus');
140+
done();
141+
});
142+
});
143+
144+
it('should give failing result if Log Analytics is not enabled for ACR', function(done) {
145+
const cache = createCache([containerRegistries[0]], [diagnosticSettings[1]]);
146+
acrLogAnalyticsEnabled.run(cache, {}, (err, results) => {
147+
expect(results.length).to.equal(1);
148+
expect(results[0].status).to.equal(2);
149+
expect(results[0].message).to.include('Logging is not enabled for container registry');
150+
expect(results[0].region).to.equal('eastus');
151+
done();
152+
});
153+
});
154+
});
155+
});

0 commit comments

Comments
 (0)