Skip to content

Commit

Permalink
Merge pull request #476 from inspec/f/alert_rule_template
Browse files Browse the repository at this point in the history
F/alert rule template
  • Loading branch information
sathish-progress authored Dec 9, 2021
2 parents c109501 + e106e91 commit 1d415ff
Show file tree
Hide file tree
Showing 7 changed files with 344 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ The following is a list of static resources.
- [azure_role_definitions](docs/resources/azure_role_definitions.md)
- [azure_security_center_policy](docs/resources/azure_security_center_policy.md)
- [azure_security_center_policies](docs/resources/azure_security_center_policies.md)
- [azure_sentinel_alert_rule_template](docs/resources/azure_sentinel_alert_rule_template.md)
- [azure_sentinel_alert_rule_templates](docs/resources/azure_sentinel_alert_rule_templates.md)
- [azure_sql_database](docs/resources/azure_sql_database.md)
- [azure_sql_databases](docs/resources/azure_sql_databases.md)
- [azure_sql_server](docs/resources/azure_sql_server.md)
Expand Down
107 changes: 107 additions & 0 deletions docs/resources/azure_sentinel_alert_rule_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
title: About the azure_sentinel_alert_rule_template Resource
platform: azure
---

# azure_sentinel_alert_rule_template

Use the `azure_sentinel_alert_rule_template` InSpec audit resource to test properties of an Azure Sentinel alert rule template.

See the [`Azure alert rule templates documentation`](https://docs.microsoft.com/en-us/rest/api/securityinsights/alert-rule-templates/list) for additional information.

## Azure REST API version, endpoint, and HTTP client parameters

This resource interacts with api versions supported by the resource provider.
The `api_version` can be defined as a resource parameter.
If not provided, the latest version will be used.
For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).

Unless defined, `azure_cloud` global endpoint, and default values for the HTTP client will be used.
For more information, refer to the resource pack [README](../../README.md).

## Availability

### Installation

This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure).
For an example `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).

## Syntax

`resource_group`, `alert_rule_template_id`, and `workspace_name` are required parameters.

```ruby
describe azure_sentinel_alert_rule_template(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME', alert_rule_template_id: 'ALERT_RULE_TEMPLATE_ID') do
#...
end
```

## Parameters

| Name | Description |
|--------------------------------|-----------------------------------------------------------------------------------|
| resource_group | Azure resource group that the targeted resource resides in. |
| workspace_name | Name for the workspace_name that you want to create your Sentinel alert rule template in. |
| alert_rule_template_id | The Sentinel alert rule template name. |

All the parameter sets needs be provided for a valid query:

- `resource_group`
- `workspace_name`
- `alert_rule_template_id`

## Properties

| Name | Description |
|--------------------------------|----------------------------------------------------------------------------------|
| name | Name of the Azure resource to test. |
| id | The Sentinel alert rule template type. |
| properties | The Properties of the Resource. |
| type | Azure resource type. |
| kind | The alert rule kind. |
| properties.severity | The severity for alerts created by this alert rule. |
| properties.status| The alert rule template status. |
| properties.triggerThreshold | The threshold triggers this alert rule. |
| properties.displayName| The display name for alert rule template. |
| properties.triggerOperator | The operation against the threshold that triggers alert rule. |
| properties.queryPeriod | The period (in ISO 8601 duration format) that this alert rule looks at. |
| properties.queryFrequency | The frequency (in ISO 8601 duration format) for this alert rule to run. |
## Examples

### Test if properties match

```ruby
describe azure_sentinel_alert_rule_template(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME', alert_rule_template_id: 'ALERT_RULE_TEMPLATE_ID') do
its('name') { should eq 'RESOURCE_NAME' }
its('type') { should eq 'Microsoft.SecurityInsights/AlertRuleTemplates' }
its('kind') { should eq 'ALERT_RULE_KIND' }
its('properties.triggerThreshold') { should eq INTEGER }
its('properties.status') { should eq 'STATUS' }
its('properties.displayName') { should eq 'ALERT_RULE_DISPLAY_NAME' }
its('properties.triggerOperator') { should eq 'OPERATOR' }
its('properties.queryPeriod') { should eq 'PERIOD' }
its('properties.queryFrequency') { should eq 'FREQUENCY' }
its('properties.severity') { should eq 'ALERT_SEVERITY' }
end
```


### Test that a Sentinel alert rule template exists

```ruby
describe azure_sentinel_alert_rule_template(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME', alert_rule_template_id: 'ALERT_RULE_TEMPLATE_ID') do
it { should exist }
end
```

### Test that a Sentinel alert rule template does not exist

```ruby
describe azure_sentinel_alert_rule_template(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME', alert_rule_template_id: 'ALERT_RULE_TEMPLATE_ID') do
it { should_not exist }
end
```

## Azure Permissions

Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be setup with a `contributor` role on the subscription you wish to test.
105 changes: 105 additions & 0 deletions docs/resources/azure_sentinel_alert_rule_templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: About the azure_sentinel_alert_rule_templates Resource
platform: azure
---

# azure_sentinel_alert_rule_templates

Use the `azure_sentinel_alert_rule_templates` InSpec audit resource to test properties related to alert rule templates for a resource group or the entire subscription.

See the [`Azure alert rule templates documentation`](https://docs.microsoft.com/en-us/rest/api/securityinsights/alert-rule-templates/list) for additional information.

## Azure Rest API Version, Endpoint, And HTTP Client Parameters

This resource interacts with API versions supported by the resource provider.
The `api_version` can be defined as a resource parameter.
If not provided, the latest version will be used.
For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).

Unless defined, `azure_cloud` global endpoint, and default values for the HTTP client will be used.
For more information, refer to the resource pack [README](../../README.md).

## Availability

### Installation

This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure).
For an example `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).

## Syntax

An `azure_sentinel_alert_rule_templates` resource block returns all Azure alert rule templates, either within a Resource Group (if provided), or within an entire Subscription.

```ruby
describe azure_sentinel_alert_rule_templates(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME') do
#...
end
```

`resource_group` and `workspace_name` are required parameters.


## Parameters

| Name | Description |
|-----------------------------|-----------------------------------------------------------------------------------|
| resource_group | Azure resource group that the targeted resource resides in. |
| workspace_name | Azure workspace Name for which alert rule templates are being retrieved.|

## Properties

| Property | Description | Filter Criteria<superscript>*</superscript> |
|-----------------|--------------------------------------------------------|-----------------|
| names | A list of the unique resource names. | `name` |
| ids | A list of alert rule templates IDs . | `id` |
| properties | A list of properties for the resource | `properties` |
| types | A list of types for each resource. | `type` |
| severities | The severity for alerts created by this alert rule. | `severity` |
| statuses | The status of the alert rule. | `status` |
| triggerThresholds | The email of the user the incident is assigned to. | `triggerThreshold` |
| displayNames| The user principal name of the user the incident is assigned to. | `displayName` |
| triggerOperators | The name of the user the incident is assigned to. | `triggerOperator` |
|queryPeriods| The List of period (in ISO 8601 duration format) that this alert rule looks at. |`queryPeriod`|
|queryFrequencies| The List of frequency (in ISO 8601 duration format) for this alert rule to run.|`queryFrequency`|

<superscript>*</superscript> For information on how to use filter criteria on plural resources refer to [FilterTable usage](https://github.com/inspec/inspec/blob/master/dev-docs/filtertable-usage.md).

## Examples

### Test if properties matches

```ruby
describe azure_sentinel_alert_rule_templates(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME') do
its('names') { should include 'RESOURCE_NAME' }
its('types') { should include 'Microsoft.SecurityInsights/AlertRuleTemplates' }
its('kinds') { should include 'ALERT_RULE_KIND' }
its('triggerThresholds') { should include INTEGER }
its('statuses') { should include 'STATUS' }
its('severities') { should include 'ALERT_SEVERITY' }
its('queryFrequencies') { should include 'FREQUENCY' }
its('queryPeriods') { should include 'PERIOD' }
its('triggerOperators') { should include 'OPERATOR' }
its('displayNames') { should include 'ALERT_RULE_DISPLAY_NAME' }
end
```

### Test if any alert rule templates exist in the resource group

```ruby
describe azure_sentinel_alert_rule_templates(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME') do
it { should exist }
end
```

### Test that there aren't any alert rule templates in a resource group

```ruby
# Should not exist if no alert rule templates are in the resource group
describe azure_sentinel_alert_rule_templates(resource_group: 'RESOURCE_GROUP', workspace_name: 'WORKSPACE_NAME') do
it { should_not exist }
end
```

## Azure Permissions

Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be setup with a `contributor` role on the subscription you wish to test.
27 changes: 27 additions & 0 deletions libraries/azure_sentinel_alert_rule_template.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'azure_generic_resource'

class AzureSentinelAlertRuleTemplate < AzureGenericResource
name 'azure_sentinel_alert_rule_template'
desc 'Verifies settings for an Sentinel Alert Rule Template'
example <<-EXAMPLE
describe azure_alert_rule_template(resource_group: 'example', workspace_name: 'workspaceName', alert_rule_template_id: 'alert_rule_template_id') do
it { should exit }
end
EXAMPLE

def initialize(opts = {})
# Options should be Hash type. Otherwise Ruby will raise an error when we try to access the keys.
raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)

opts[:resource_provider] = specific_resource_constraint('Microsoft.OperationalInsights/workspaces', opts)
opts[:required_parameters] = %i(workspace_name)
opts[:resource_path] = [opts[:workspace_name], 'providers/Microsoft.SecurityInsights/alertRuleTemplates/'].join('/')
opts[:resource_identifiers] = %i(alert_rule_template_id)
# static_resource parameter must be true for setting the resource_provider in the backend.
super(opts, true)
end

def to_s
super(AzureSentinelAlertRuleTemplate)
end
end
61 changes: 61 additions & 0 deletions libraries/azure_sentinel_alert_rule_templates.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'azure_generic_resources'

class AzureSentinelAlertRuleTemplates < AzureGenericResources
name 'azure_sentinel_alert_rule_templates'
desc 'Verifies settings for Azure Alert Rule Templates'
example <<-EXAMPLE
azure_alert_rule_templates(resource_group: 'example', workspace_name: 'workspaceName') do
it{ should exist }
end
EXAMPLE

attr_reader :table

def initialize(opts = {})
# Options should be Hash type. Otherwise Ruby will raise an error when we try to access the keys.
raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)

opts[:resource_provider] = specific_resource_constraint('Microsoft.OperationalInsights/workspaces', opts)
opts[:required_parameters] = %i(workspace_name)
opts[:resource_path] = [opts[:workspace_name], 'providers/Microsoft.SecurityInsights/alertRuleTemplates/'].join('/')
# static_resource parameter must be true for setting the resource_provider in the backend.
super(opts, true)

# Check if the resource is failed.
# It is recommended to check that after every usage of superclass methods or API calls.
return if failed_resource?

# Define the column and field names for FilterTable.
# - column: It is defined as an instance method, callable on the resource, and present `field` values in a list.
# - field: It has to be identical with the `key` names in @table items that will be presented in the FilterTable.
# @see https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md

# FilterTable is populated at the very end due to being an expensive operation.
populate_filter_table_from_response
end

def to_s
super(AzureSentinelAlertRuleTemplates)
end

private

def flatten_hash(hash)
hash.each_with_object({}) do |(k, v), h|
if v.is_a? Hash
flatten_hash(v).map do |h_k, h_v|
h["#{k}_#{h_k}".to_sym] = h_v
end
else
h[k] = v
end
end
end

def populate_table
@resources.each do |resource|
resource = resource.merge(resource[:properties])
@table << flatten_hash(resource)
end
end
end
17 changes: 17 additions & 0 deletions test/unit/resources/azure_sentinel_alert_rule_template_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require_relative 'helper'
require 'azure_sentinel_alert_rule_template'

class AzureAlertRuleTemplateConstructorTest < Minitest::Test
def test_empty_param_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new }
end

# resource_provider should not be allowed.
def test_resource_provider_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(resource_provider: 'some_type') }
end

def test_resource_group
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(name: 'my-name') }
end
end
25 changes: 25 additions & 0 deletions test/unit/resources/azure_sentinel_alert_rule_templates_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require_relative 'helper'
require 'azure_sentinel_alert_rule_templates'

class AzureAlertRuleTemplatesConstructorTest < Minitest::Test
# resource_type should not be allowed.
def test_resource_type_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(resource_provider: 'some_type') }
end

def tag_value_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(tag_value: 'some_tag_value') }
end

def tag_name_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(tag_name: 'some_tag_name') }
end

def test_resource_id_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(resource_id: 'some_id') }
end

def test_name_not_ok
assert_raises(ArgumentError) { AzureSentinelAlertRuleTemplate.new(name: 'some_name') }
end
end

0 comments on commit 1d415ff

Please sign in to comment.