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

Add azure_network_watcher(s) resources #349

Merged
merged 3 commits into from
Dec 4, 2020
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ The static resources derived from the generic resources prepended with `azure_`
- [azure_network_interfaces](docs/resources/azure_network_interfaces.md)
- [azure_network_security_group](docs/resources/azure_network_security_group.md)
- [azure_network_security_groups](docs/resources/azure_network_security_groups.md)
- [azure_network_watcher](docs/resources/azure_network_watcher.md)
- [azure_network_watchers](docs/resources/azure_network_watchers.md)
- [azure_policy_definition](docs/resources/azure_policy_definition.md)
- [azure_policy_definitions](docs/resources/azure_policy_definitions.md)
- [azure_postgresql_database](docs/resources/azure_postgresql_database.md)
Expand Down
113 changes: 113 additions & 0 deletions docs/resources/azure_network_watcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
title: About the azure_network_watcher Resource
platform: azure
---

# azure_network_watcher

Use the `azure_network_watcher` InSpec audit resource to test properties of an Azure network watcher.

## 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_network_watcher` resource block identifies a network watcher by `name` and `resource_group` or the `resource_id`.
```ruby
describe azure_network_watcher(resource_group: 'resourceGroupName', name: 'networkWatcherName') do
it { should exist }
end
```
```ruby
describe azure_network_watcher(resource_id: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkWatchers/{networkWatcherName}') do
it { should exist }
end
```
## Parameters

| Name | Description |
|--------------------------------|-----------------------------------------------------------------------------------|
| resource_group | Azure resource group that the network watcher resides in. `resourceGroupName` |
| name | Name of the network watcher to test. `networkWatcherName` |
| resource_id | The unique resource ID. `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkWatchers/{networkWatcherName}` |
| flow_logs_api_version | The flow log status endpoint api version used for creating `flow_logs` property. The latest version will be used unless provided. A network security group within the same region can be targeted for getting the flow log statuses. For more, see [here](https://docs.microsoft.com/en-us/rest/api/network-watcher/networkwatchers/getflowlogstatus).|
| nsg_resource_id | The unique resource ID of the network security group being targeted to get the flow log statuses. `/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/networkSecurityGroups/{networkSecurityGroupName}` |
| nsg_resource_group | The resource group of the network security group being targeted to get the flow log statuses. This requires `nsg_name` to be provided. |
| nsg_name | The name of the network security group being targeted to get the flow log statuses. This requires `nsg_resource_group` to be provided.|


Either one of the parameter sets can be provided for a valid query:
- `resource_id`
- `resource_group` and `name`

## Properties

| Property | Description |
|-----------------------|-------------|
| provisioning_state | The provisioning state of the network watcher resource. For the valid values, see [here](https://docs.microsoft.com/en-us/rest/api/network-watcher/networkwatchers/get#provisioningstate). |
| flow_logs | Information on the configuration of flow log and traffic analytics (optional) in [this format](https://docs.microsoft.com/en-us/rest/api/network-watcher/networkwatchers/getflowlogstatus#flowloginformation). All properties can be accessed via dot notation, e.g.: `flow_logs.properties.enabled`. This resource supports targeting network security groups defined at resource creation only. |

For properties applicable to all resources, such as `type`, `name`, `id`, `properties`, refer to [`azure_generic_resource`](azure_generic_resource.md#properties).

Also, refer to [Azure documentation](https://docs.microsoft.com/en-us/rest/api/network-watcher/networkwatchers/get#networkwatcher) for other properties available.
Any attribute in the response may be accessed with the key names separated by dots (`.`).

## Examples

### Test the Location of a Network Watcher
```ruby
describe azure_network_watcher(resource_group: 'resourceGroupName', name: 'networkWatcherName') do
its('location') { should cmp 'eastus' }
end
```
### Test the Flow Log Status of a Network Security Group
```ruby
describe azure_network_watcher(resource_group: 'resourceGroupName', name: 'networkWatcherName', nsg_resource_group: 'nsg_rg', nsg_name: 'nsg_eastus') do
its('flow_logs.properties.enabled') { should be true }
its('flow_logs.properties.retentionPolicy.days') { should be >= 90 }
end
```
### Loop through Network Security Groups with the Resource ID
```ruby
azure_network_security_groups.where(location: 'eastus').ids.each do |nsg_id|
describe azure_network_watcher(resource_group: 'resourceGroupName', name: 'networkWatcherName', nsg_resource_id: nsg_id) do
its('flow_logs.properties.enabled') { should be true }
its('flow_logs.properties.retentionPolicy.days') { should be >= 90 }
end
end
```
See [integration tests](../../test/integration/verify/controls/azurerm_network_watcher.rb) for more examples.

## Matchers

This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [Universal Matchers page](https://docs.chef.io/inspec/matchers/).

### exists
```ruby
# If we expect 'networkWatcherName' to always exist
describe azure_network_watcher(resource_group: 'resourceGroupName', name: 'networkWatcherName') do
it { should exist }
end

# If we expect 'networkWatcherName' to never exist
describe azure_network_watcher(resource_group: 'resourceGroupName', name: 'networkWatcherName') 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.
84 changes: 84 additions & 0 deletions docs/resources/azure_network_watchers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: About the azure_network_watchers Resource
platform: azure
---

# azure_network_watchers

Use the `azure_network_watchers` InSpec audit resource to test properties and configuration of multiple Azure network watchers.

## 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_network_watchers` resource block returns all network watchers, either within a Resource Group (if provided), or within an entire Subscription.
```ruby
describe azure_network_watchers do
#...
end
```
or
```ruby
describe azure_network_watchers(resource_group: 'my-rg') do
#...
end
```
## Parameters

- `resource_group` (Optional)

## Properties

|Property | Description | Filter Criteria<superscript>*</superscript> |
|---------------|--------------------------------------------------------------------------------------|-----------------|
| ids | A list of the unique resource ids. | `id` |
| locations | A list of locations for all the resources being interrogated. | `location` |
| names | A list of names of all the resources being interrogated. | `name` |
| tags | A list of `tag:value` pairs defined on the resources being interrogated. | `tags` |

<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 that an Example Resource Group has the Named Network Watcher
```ruby
describe azure_network_watchers(resource_group: 'ExampleGroup') do
its('names') { should include('NetworkWatcherName') }
end
```
## Matchers

This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [Universal Matchers page](https://www.inspec.io/docs/reference/matchers/).

### exists

The control will pass if the filter returns at least one result. Use `should_not` if you expect zero matches.
```ruby
# If we expect 'ExampleGroup' Resource Group to have Network Watchers
describe azure_network_watchers(resource_group: 'ExampleGroup') do
it { should exist }
end

# If we expect 'EmptyExampleGroup' Resource Group to not have Network Watchers
describe azure_network_watchers(resource_group: 'EmptyExampleGroup') 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.
2 changes: 2 additions & 0 deletions docs/resources/azurerm_network_watcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: About the azurerm_network_watcher Resource
platform: azure
---

> <b>WARNING</b> This resource will be deprecated in InSpec Azure Resource Pack version **2**. Please start using fully backward compatible [`azure_network_watcher`](azure_network_watcher.md) InSpec audit resource.

# azurerm\_network\_watcher

Use the `azurerm_network_watcher` InSpec audit resource to test properties of an Azure
Expand Down
2 changes: 2 additions & 0 deletions docs/resources/azurerm_network_watchers.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: About the azurerm_network_watchers Resource
platform: azure
---

> <b>WARNING</b> This resource will be deprecated in InSpec Azure Resource Pack version **2**. Please start using fully backward compatible [`azure_networke_watchers`](azure_network_watchers.md) InSpec audit resource.

# azurerm\_network\_watchers

Use the `azurerm_network_watchers` InSpec audit resource to verify that a Network Watcher
Expand Down
104 changes: 104 additions & 0 deletions libraries/azure_network_watcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
require 'azure_generic_resource'

class AzureNetworkWatcher < AzureGenericResource
name 'azure_network_watcher'
desc 'Verifies settings for Network Watchers'
example <<-EXAMPLE
describe azure_network_watcher(resource_group: 'example', name: 'name') do
its(name) { should eq 'name'}
end
EXAMPLE

# This is for backward compatibility.
attr_accessor :nsg

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.Network/networkWatchers', opts)
opts[:allowed_parameters] = %i(flow_logs_api_version nsg_resource_id nsg_resource_group nsg_name)
opts[:flow_logs_api_version] ||= 'latest'

# static_resource parameter must be true for setting the resource_provider in the backend.
super(opts, true)
end

def to_s
super(AzureNetworkWatcher)
end

def provisioning_state
return unless exists?
properties&.provisioningState
end

def flow_logs
return unless exists?
# This is for backward compatibility. !!! NOT RECOMMENDED !!!
# nsg is the name of the network security group.
# It can be defined on the instance of this resource.
# nw = azure_network_watcher(resource_group: resource_group, name: nw_name)
# nw.nsg = nsg
# It must be within the same resource group with the network watcher.
if nsg
target_resource_id = validate_resource_uri(
{
resource_uri:
"/resourceGroups/#{@opts[:resource_group]}/providers/Microsoft.Network/networkSecurityGroups/#{nsg}",
add_subscription_id: true,
},
)
elsif @opts[:nsg_resource_group] && @opts[:nsg_name]
# network security group can be provided with its resource group and name.
target_resource_id = validate_resource_uri(
{
resource_uri:
"/resourceGroups/#{@opts[:nsg_resource_group]}/providers/Microsoft.Network/networkSecurityGroups/"\
"#{@opts[:nsg_name]}",
add_subscription_id: true,
},
)
elsif @opts[:nsg_resource_id]
# network security group can be provided with its resource id.
target_resource_id = @opts[:nsg_resource_id]
else
raise ArgumentError,
'The resource group (nsg_resource_group) and the name (nsg_name) of the network security group or '\
'the resource id (nsg_resource_id) must be provided at resource initiation.'
end
req_body_hash = {
targetResourceId: target_resource_id,
}
additional_resource_properties(
{
property_name: 'flow_logs',
property_endpoint: id + '/queryFlowLogStatus',
api_version: @opts[:flow_logs_api_version],
method: 'post',
req_body: JSON.generate(req_body_hash),
headers: { 'Content-Type' => 'application/json' },
},
)
end
end

# Provide the same functionality under the old resource name.
# This is for backward compatibility.
class AzurermNetworkWatcher < AzureNetworkWatcher
name 'azurerm_network_watcher'
desc 'Verifies settings for Network Watchers'
example <<-EXAMPLE
describe azurerm_network_watcher(resource_group: 'example', name: 'name') do
its(name) { should eq 'name'}
end
EXAMPLE

def initialize(opts = {})
Inspec::Log.warn Helpers.resource_deprecation_message(@__resource_name__, AzureNetworkWatcher.name)
# For backward compatibility.
opts[:api_version] ||= '2018-02-01'
opts[:flow_logs_api_version] ||= '2019-04-01'
super
end
end
64 changes: 64 additions & 0 deletions libraries/azure_network_watchers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require 'azure_generic_resources'

class AzureNetworkWatchers < AzureGenericResources
name 'azure_network_watchers'
desc 'Verifies settings for Network Watchers'
example <<-EXAMPLE
azure_network_watchers(resource_group: 'example') 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.Network/networkWatchers', opts)
opts[:allowed_parameters] = %i(resource_group)

# 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 inherited methods or making API calls.
return if failed_resource?

# Define the column and field names for FilterTable.
# In most cases, the `column` should be the pluralized form of the `field`.
# @see https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md
table_schema = [
{ column: :names, field: :name },
{ column: :ids, field: :id },
{ column: :tags, field: :tags },
{ column: :locations, field: :location },
]

# FilterTable is populated at the very end due to being an expensive operation.
AzureGenericResources.populate_filter_table(:table, table_schema)
end

def to_s
super(AzureNetworkWatchers)
end
end

# Provide the same functionality under the old resource name.
# This is for backward compatibility.
class AzurermNetworkWatchers < AzureNetworkWatchers
name 'azurerm_network_watchers'
desc 'Verifies settings for Network Watchers'
example <<-EXAMPLE
azurerm_network_watchers(resource_group: 'example') do
it{ should exist }
end
EXAMPLE

def initialize(opts = {})
Inspec::Log.warn Helpers.resource_deprecation_message(@__resource_name__, AzureNetworkWatchers.name)
# For backward compatibility.
opts[:api_version] ||= '2018-02-01'
super
end
end
Loading