Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M/azure/api management service has tags #2028

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
3 changes: 3 additions & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,9 @@ module.exports = {
'synapseWorkspaceAdAuthEnabled' : require(__dirname + '/plugins/azure/synapse/synapseWorkspaceAdAuthEnabled.js'),
'synapseWorkspacPrivateEndpoint': require(__dirname + '/plugins/azure/synapse/synapseWorkspacPrivateEndpoint.js'),

'apiInstanceManagedIdentity' : require(__dirname + '/plugins/azure/apiManagement/apiInstanceManagedIdentity.js'),
'apiInstanceHasTags' : require(__dirname + '/plugins/azure/apiManagement/apiInstanceHasTags.js'),

},
github: {
'publicKeysRotated' : require(__dirname + '/plugins/github/users/publicKeysRotated.js'),
Expand Down
5 changes: 5 additions & 0 deletions helpers/azure/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,11 @@ var calls = {
url: 'https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Databricks/workspaces?api-version=2023-02-01'
}
},
apiManagementService: {
list: {
url: 'https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.ApiManagement/service?api-version=2022-08-01'
}
},
// For CIEM
aad: {
listRoleAssignments: {
Expand Down
1 change: 1 addition & 0 deletions helpers/azure/locations.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,6 @@ module.exports = {
containerApps: locations,
batchAccounts: locations,
machineLearning: locations,
apiManagementService: locations,
synapse: locations
};
1 change: 1 addition & 0 deletions helpers/azure/locations_gov.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@ module.exports = {
computeGalleries: locations,
databricks: locations,
containerApps: locations,
apiManagementService: locations,
synapse: locations
};
3 changes: 3 additions & 0 deletions helpers/azure/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,5 +306,8 @@ module.exports = {
},
machineLearning: {
listWorkspaces: 'id'
},
apiManagementService: {
list: 'id'
}
};
52 changes: 52 additions & 0 deletions plugins/azure/apiManagement/apiInstanceHasTags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
var async = require('async');
var helpers = require('../../../helpers/azure');

module.exports = {
title: 'API Management Instance Has Tags',
category: 'API Management',
domain: 'Developer Tools',
severity: 'Medium',
description: 'Ensures that Azure API Management instance has tags associated.',
more_info: 'Tags help you to group resources together that are related to or associated with each other. It is a best practice to tag cloud resources to better organize and gain visibility into their usage.',
link: 'https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources',
recommended_action: 'Modify API Management instance and add tags.',
apis: ['apiManagementService:list'],
realtime_triggers: ['microsoftapimanagement:service:write','microsoftapimanagement:service:delete','microsoftresources:tags:write'],

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

async.each(locations.apiManagementService, function(location, rcb){
var apiManagementService = helpers.addSource(cache, source,
['apiManagementService', 'list', location]);

if (!apiManagementService) return rcb();

if (apiManagementService.err || !apiManagementService.data) {
helpers.addResult(results, 3, 'Unable to query API Management instances:' + helpers.addError(apiManagementService), location);
return rcb();
}

if (!apiManagementService.data.length) {
helpers.addResult(results, 0, 'No existing API Management instances found', location);
return rcb();
}

for (let apiInstance of apiManagementService.data) {
if (!apiInstance.id) continue;

if (apiInstance.tags && Object.entries(apiInstance.tags).length > 0) {
helpers.addResult(results, 0, 'API Management instance has tags associated', location, apiInstance.id);
} else {
helpers.addResult(results, 2, 'API Management instance does not have tags associated', location, apiInstance.id);
}
}

rcb();
}, function(){
callback(null, results, source);
});
}
};
101 changes: 101 additions & 0 deletions plugins/azure/apiManagement/apiInstanceHasTags.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
var expect = require('chai').expect;
var apiInstanceHasTags = require('./apiInstanceHasTags.js');

const apiManagementService = [
{
"etag": "AAAAAAGIUI4=",
"publisherEmail": "[email protected]",
"publisherName": "dummy",
"notificationSenderEmail": "[email protected]",
"provisioningState": "Succeeded",
"targetProvisioningState": "",
"identity": null,
"zones": null,
"tags": {},
"location": "East US",
"id": "/subscriptions/123456/resourceGroups/testfunction_group/providers/Microsoft.ApiManagement/service/test",
"name": "meerab",
"type": "Microsoft.ApiManagement/service"
},
{
"etag": "AAAAAAGIUI4=",
"publisherEmail": "[email protected]",
"publisherName": "dummy",
"notificationSenderEmail": "[email protected]",
"provisioningState": "Succeeded",
"targetProvisioningState": "",
"identity": {
"type": "SystemAssigned",
"principalId": "fdd1f197-d0e0-4d04-a5ef-9dbb654afd14",
"tenantId": "d207c7bd-fcb1-4dd3-855a-cfd2f9b651e8"
},
"zones": null,
"location": "East US",
"tags": {"key": "value"},
"id": "/subscriptions/123456/resourceGroups/testfunction_group/providers/Microsoft.ApiManagement/service/test",
"name": "meerab",
"type": "Microsoft.ApiManagement/service"
}
];

const createCache = (apiManagementService, err) => {
return {
apiManagementService: {
list: {
'eastus': {
data: apiManagementService,
err: err
}
}
}
}
};

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

it('should give pass result if No existing API Management service instances found', function (done) {
const cache = createCache([]);
apiInstanceHasTags.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No existing API Management instances found');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give unknown result if Unable to query API Management service instances', function (done) {
const cache = createCache(null, 'Error');
apiInstanceHasTags.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query API Management instances');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give passing result if API Management service instances has tags associated', function (done) {
const cache = createCache([apiManagementService[1]]);
apiInstanceHasTags.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('API Management instance has tags associated');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give failing result if API Management service instances does not have tags associated', function (done) {
const cache = createCache([apiManagementService[0]]);
apiInstanceHasTags.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('API Management instance does not have tags associated');
expect(results[0].region).to.equal('eastus');
done();
});
});
});
});
52 changes: 52 additions & 0 deletions plugins/azure/apiManagement/apiInstanceManagedIdentity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
var async = require('async');
var helpers = require('../../../helpers/azure');

module.exports = {
title: 'API Management Instance Managed Identity',
category: 'API Management',
domain: 'Developer Tools',
severity: 'Medium',
description: 'Ensures that Azure API Management instance has managed identity enabled.',
more_info: 'Enabling managed identities eliminate the need for developers having to manage credentials by providing an identity for the Azure resource in Azure AD and using it to obtain Azure Active Directory (Azure AD) tokens.',
link: 'https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-use-managed-service-identity',
recommended_action: 'Modify API Management instance and add managed identity.',
apis: ['apiManagementService:list'],
realtime_triggers: ['microsoftapimanagement:service:write','microsoftapimanagement:service:delete'],

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

async.each(locations.apiManagementService, function(location, rcb){
var apiManagementService = helpers.addSource(cache, source,
['apiManagementService', 'list', location]);

if (!apiManagementService) return rcb();

if (apiManagementService.err || !apiManagementService.data) {
helpers.addResult(results, 3, 'Unable to query API Management instances:' + helpers.addError(apiManagementService), location);
return rcb();
}

if (!apiManagementService.data.length) {
helpers.addResult(results, 0, 'No existing API Management instances found', location);
return rcb();
}

for (let apiInstance of apiManagementService.data) {
if (!apiInstance.id) continue;

if (apiInstance.identity) {
helpers.addResult(results, 0, 'API Management instance has managed identity enabled', location, apiInstance.id);
} else {
helpers.addResult(results, 2, 'API Management instance does not have managed identity enabled', location, apiInstance.id);
}
}

rcb();
}, function(){
callback(null, results, source);
});
}
};
101 changes: 101 additions & 0 deletions plugins/azure/apiManagement/apiInstanceManagedIdentity.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
var expect = require('chai').expect;
var apiInstanceManagedIdentity = require('./apiInstanceManagedIdentity.js');

const apiManagementService = [
{
"etag": "AAAAAAGIUI4=",
"publisherEmail": "[email protected]",
"publisherName": "dummy",
"notificationSenderEmail": "[email protected]",
"provisioningState": "Succeeded",
"targetProvisioningState": "",
"identity": null,
"zones": null,
"location": "East US",
"tags": {},
"id": "/subscriptions/123456/resourceGroups/testfunction_group/providers/Microsoft.ApiManagement/service/test",
"name": "meerab",
"type": "Microsoft.ApiManagement/service"
},
{
"etag": "AAAAAAGIUI4=",
"publisherEmail": "[email protected]",
"publisherName": "dummy",
"notificationSenderEmail": "[email protected]",
"provisioningState": "Succeeded",
"targetProvisioningState": "",
"identity": {
"type": "SystemAssigned",
"principalId": "fdd1f197-d0e0-4d04-a5ef-9dbb654afd14",
"tenantId": "d207c7bd-fcb1-4dd3-855a-cfd2f9b651e8"
},
"zones": null,
"location": "East US",
"tags": {},
"id": "/subscriptions/123456/resourceGroups/testfunction_group/providers/Microsoft.ApiManagement/service/test",
"name": "meerab",
"type": "Microsoft.ApiManagement/service"
}
];

const createCache = (apiManagementService, err) => {
return {
apiManagementService: {
list: {
'eastus': {
data: apiManagementService,
err: err
}
}
}
}
};

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

it('should give pass result if No existing API Management service instances found', function (done) {
const cache = createCache([]);
apiInstanceManagedIdentity.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No existing API Management instances found');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give unknown result if Unable to query API Management service instances:', function (done) {
const cache = createCache(null, 'Error');
apiInstanceManagedIdentity.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query API Management instances:');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give passing result if API Management service instances has managed identity enabled', function (done) {
const cache = createCache([apiManagementService[1]]);
apiInstanceManagedIdentity.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('API Management instance has managed identity enabled');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give failing result if API Management service instances does not have managed identity enabled', function (done) {
const cache = createCache([apiManagementService[0]]);
apiInstanceManagedIdentity.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('API Management instance does not have managed identity enabled');
expect(results[0].region).to.equal('eastus');
done();
});
});
});
});
Loading