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

F/sentinel incidents #459

Merged
merged 19 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from 15 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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,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_incidents_resource](docs/resources/azure_sentinel_incidents_resource.md)
- [azure_sentinel_incidents_resources](docs/resources/azure_sentinel_incidents_resources.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
106 changes: 106 additions & 0 deletions docs/resources/azure_sentinel_incidents_resource.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: About the azure_sentinel_incidents_resource Resource
platform: azure
---

# azure_sentinel_incidents_resource

Use the `azure_sentinel_incidents_resource` InSpec audit resource to test properties of an Azure sentinel_incident.

## 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).
For api related info : [`Azure sentinel_incident Docs`](https://docs.microsoft.com/en-us/rest/api/securityinsights/incidents/get).


## 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` and `incident_id`, `workspace_name` must be given as parameters.

```ruby
describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do

end
```

## Parameters

| Name | Description |
|--------------------------------|-----------------------------------------------------------------------------------|
| resource_group | Azure resource group that the targeted resource resides in. `MyResourceGroup` |
| workspace_name | Name for the Workspace that you want to create your sentinel_incident in.. |
| incident_id | The sentinel_incident Name. |

All the parameter sets needs be provided for a valid query:
- `resource_group` , `workspace_name` and `incident_id`
## Properties

| Name | Description |
|--------------------------------|----------------------------------------------------------------------------------|
| name | Name of the Azure resource to test. `MyDf` |
| id | The sentinel_incident type. |
| properties | The Properties of the Resource. |
| properties.severity | The severity of the incident | `properties.severity` |
| properties.status| The status of the incident | `properties.status` |
| properties.owner.email | The email of the user the incident is assigned to. | `properties.owner.email` |
| properties.owner.userPrincipalName| The user principal name of the user the incident is assigned to. | `properties.owner.userPrincipalName` |
| properties.owner.assignedTo | The name of the user the incident is assigned to. | `properties.owner.assignedTo` |

## Examples

### Test if properties matches

```ruby
describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do
it { should exist }
its('name') { should eq '0367ce89-78ad-4009-8d90-399fad24aabf' }
its('type') { should eq 'Microsoft.SecurityInsights/Incidents' }
its('properties.severity') { should eq 'Informational' }
its('properties.status') { should eq 'New' }
its('properties.owner.email') { should eq 'owner_email' }
its('properties.owner.userPrincipalName') { should eq 'samir.anand_progress.com#EXT#@getchef.onmicrosoft.com' }
its('properties.owner.assignedTo') { should eq 'owner_name' }
end
```


### Test that a sentinel_incident exists

```ruby
describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do
it { should exist }
end
```

### Test that a sentinel_incident does not exist

```ruby
describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: 'should not exit') do
it { should_not exist }
end
```

### Test properties of a sentinel_incident

```ruby
describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: 'incident_id1') do
its('name') { should eq 'incident_id1' }
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.
98 changes: 98 additions & 0 deletions docs/resources/azure_sentinel_incidents_resources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: About the azure_sentinel_incidents_resources Resource
platform: azure
---

# azure_sentinel_incidents_resources

Use the `azure_sentinel_incidents_resources` InSpec audit resource to test properties related to sentinel_incident for a resource group or the entire subscription.

## 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).
For api related info : [`Azure sentinel_incident Docs`](https://docs.microsoft.com/en-us/rest/api/securityinsights/incidents/list).
## 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_incidents_resources` resource block returns all Azure sentinel_incident, either within a Resource Group (if provided), or within an entire Subscription.

```ruby
describe azure_sentinel_incidents_resources(resource_group: 'example', workspace_name: 'fn') do
#...
end
```
`resource_group` and `workspace_name` must be given as parameters.


## Parameters

| Name | Description |
|--------------------------------|-----------------------------------------------------------------------------------|
| resource_group | Azure resource group that the targeted resource resides in. `MyResourceGroup` |
| workspace_name | Azure Workspace Name for which sentinel_incident are being retrieved.|

## Properties

| Property | Description | Filter Criteria<superscript>*</superscript> |
|-----------------|---------------------------------------------------------|-----------------|
| names | A list of the unique resource names. | `name` |
| ids | A list of sentinel_incident IDs . | `id` |
| properties | A list of properties for the resource | `properties` |
| descriptions | A list of descriptions for each resource | `description` |
| severities | The severity of the incident | `severity` |
| statuses| The status of the incident | `status` |
| owner_emails | The email of the user the incident is assigned to. | `owner_email` |
| owner_userPrincipalNames| The user principal name of the user the incident is assigned to. | `owner_userPrincipalName` |
| owner_assignedTos | The name of the user the incident is assigned to. | `owner_assignedTo` |

<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_incidents_resource(resource_group: resource_group, workspace_name: 'workspace_name') do
it { should exist }
its('names') { should include '0367ce89-78ad-4009-8d90-399fad24aabf' }
its('types') { should include 'Microsoft.SecurityInsights/Incidents' }
its('titles') { should include 'test-ana' }
its('descriptions') { should include 'test-rule' }
its('severities') { should include 'Informational' }
its('statuses') { should include 'New' }
its('owner_emails') { should include 'mailid' }
its('owner_userPrincipalNames') { should include 'mail#EXT#@getchef.onmicrosoft.com' }
its('owner_assignedTos') { should include 'Name' }
end
```

### Test if any sentinel_incident exist in the resource group

```ruby
describe azure_sentinel_incidents_resources(resource_group: 'example', workspace_name: 'fn') do
it { should exist }
end
```
### Test that there aren't any sentinel_incident in a resource group

```ruby
# Should not exist if no sentinel_incident are in the resource group
describe azure_sentinel_incidents_resources(resource_group: 'example', workspace_name: 'fake') 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.
32 changes: 32 additions & 0 deletions libraries/azure_sentinel_incidents_resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'azure_generic_resource'

class AzureSentinelIncidentsResource < AzureGenericResource
name 'azure_sentinel_incidents_resource'
desc 'get azure gateway unr ta factory.'
example <<-EXAMPLE
describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do
it { should exist }
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)
#
# Azure REST API endpoint URL format for the resource:
# GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/
# providers/Microsoft.OperationalInsights/workspaces/{workspaceName}/
# providers/Microsoft.SecurityInsights/incidents/{incidentId}?api-version=2021-04-01
#
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/incidents/'].join('/')
opts[:resource_identifiers] = %i(incident_id)
# static_resource parameter must be true for setting the resource_provider in the backend.
super(opts, true)
end

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

class AzureSentinelIncidentsResources < AzureGenericResources
name 'azure_sentinel_incidents_resources'
desc 'List azure pipelines by data factory.'
example <<-EXAMPLE
describe azure_sentinel_incidents_resources(resource_group: resource_group, workspace_name: workspace_name) do
it { should exist }
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)
# Azure REST API endpoint URL format for the resource:
# GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/
# providers/Microsoft.OperationalInsights/workspaces/{workspaceName}/
# providers/Microsoft.SecurityInsights/incidents?api-version=2021-04-01
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/incidents'].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(AzureSentinelIncidentsResources)
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
resource_group = input('resource_group', value: nil)
incident_id = input('incident_id', value: nil)
workspace_name = input('workspace_name', value: nil)
control 'azure_sentinel_incidents_resource' do

describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do
it { should exist }
its('type') { should eq 'Microsoft.OperationalInsights/workspaces' }
its('severity') { should include 'Informational' }
its('title') { should include 'test-ana' }
its('status') { should include 'new' }
its('owner.email') { should include 'samir.anand@progress.com' }
its('owner.userPrincipalName') { should include 'samir.anand@progress.com' }
its('owner.assignedTo') { should include 'Samir Anand' }
end

describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do
it { should_not exist }
end

describe azure_sentinel_incidents_resource(resource_group: resource_group, workspace_name: workspace_name, incident_id: incident_id) do
it { should_not exist }
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource_group = input('resource_group', value: nil)
incident_name = input('incident_name', value: nil)
workspace_name = input('workspace_name', value: nil)

control 'azure_sentinel_incidents_resources' do
describe azure_sentinel_incidents_resources(resource_group: resource_group, workspace_name: workspace_name) do
it { should exist }
its('names') { should include incident_name }
its('types') { should include 'Microsoft.OperationalInsights/workspaces' }
its('severity') { should include 'High' }
its('classification') { should include 'High' }
its('classificationComment') { should include 'High' }
its('classificationReason') { should include 'Closed' }
its('status') { should include 'Closed' }
its('owner.objectId') { should include 'Closed' }
its('owner.email') { should include 'Closed' }
its('owner.userPrincipalName') { should include 'Closed' }
its('owner.assignedTo') { should include 'Closed' }
its('owner.assignedTo') { should include 'incidentNumber' }
end
end
17 changes: 17 additions & 0 deletions test/unit/resources/azure_sentinel_incidents_resource_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require_relative 'helper'
require 'azure_sentinel_incidents_resource'

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

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

def test_resource_group
assert_raises(ArgumentError) { AzureSentinelIncidentsResource.new(name: 'my-name') }
end
end
Loading