mirror of
https://github.com/inspec/inspec
synced 2024-11-14 17:07:09 +00:00
Added support for checking the resource group resources
Fixes #6 Signed-off-by: Russell Seymour <russell.seymour@turtlesystems.co.uk>
This commit is contained in:
parent
c2bc6dc40d
commit
7a6cbff579
7 changed files with 296 additions and 17 deletions
49
README.md
49
README.md
|
@ -107,6 +107,47 @@ end
|
|||
|
||||
### Available Resources
|
||||
|
||||
- `azure_rg` - This resource reads information about the resources in the specified resource group
|
||||
|
||||
| Resource Name | Resources | Description |
|
||||
|---------------|-----------|-------------|
|
||||
| azure_rg | location | Where the item has been deployed |
|
||||
| | total | The total number of resources in the resource group |
|
||||
| | nic_count | Helper method to return the number of Network Interface Cards (NIC) that exist |
|
||||
| | vm_count | Helper method to return the number of Virtual Machines(VM) that exist |
|
||||
| | vnet_count | Helper method to return the number of Virtual Networks (VNET) that exist |
|
||||
| | nsg_count | Helper method to return the number of Network Security Groups (NSG) that exist |
|
||||
| | sa_count | Helper method to return the number of Storage Accounts (SA) that exist |
|
||||
| | public_ip_count | Helper method to return the number of Public IP Addresses that exist |
|
||||
| | contains | Used to determine if a specific item exists |
|
||||
|
||||
This resource also has a FilterTable which means that it is possible to check for items that do not yet have a helper method.
|
||||
|
||||
#### Test for the number of storage accounts
|
||||
|
||||
```ruby
|
||||
control 'azure-1' do
|
||||
impact 1.0
|
||||
title 'Checks that there is only one storage account in the resource group'
|
||||
|
||||
describe azure_rg(name: 'MyResourceGroup').where { type == 'Microsoft.Storage/storageAccounts' }.entries do
|
||||
its('count') { should eq 1 }
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### Ensure that a specific item exists
|
||||
|
||||
```ruby
|
||||
control 'azure-1' do
|
||||
impact 1.0
|
||||
title 'Checks a resource with the name "example-VM" exists'
|
||||
|
||||
describe azure_rg(name: 'MyResourceGroup').contains(parameter: 'name', value: 'example-VM') do
|
||||
it { should be true }
|
||||
end
|
||||
end
|
||||
|
||||
- `azure_vm` - This resource reads information about a virtual machine in the specified resource group
|
||||
|
||||
| Resource Name | Resources | Description |
|
||||
|
@ -146,21 +187,19 @@ When data disks are retrieved from a machine they are given as an array. The `w
|
|||
|
||||
**Note: This does not yet work with Managed Disks**
|
||||
|
||||
## Examples
|
||||
|
||||
### Test for 1 disk with a size greater than 10gb
|
||||
#### Test for 1 disk with a size greater than 10gb
|
||||
|
||||
```ruby
|
||||
control 'azure-1' do
|
||||
impact 1.0
|
||||
title 'Checks that the machine has exactly one data disk and it is over 10gb in size'
|
||||
|
||||
describe azurevm_image(host: 'example-01', resource_group: 'MyResourceGroup') do
|
||||
describe azure_vm(host: 'example-01', resource_group: 'MyResourceGroup') do
|
||||
its('has_disks?') { should be true }
|
||||
its('count') { should eq 1 }
|
||||
end
|
||||
|
||||
describe azurevm_image(host: 'example-01', resource_group: 'MyResourceGroup').where { disk == 0 and size > 10 } do
|
||||
describe azure_vm_datadisks(host: 'example-01', resource_group: 'MyResourceGroup').where { disk == 0 and size > 10 } do
|
||||
its('entries') { should_not be_empty }
|
||||
end
|
||||
end
|
||||
|
|
22
controls/example_rg.rb
Normal file
22
controls/example_rg.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
title 'Sample profile to test names resource group'
|
||||
|
||||
control 'azure-rg-1.0' do
|
||||
impact 1.0
|
||||
title 'Ensure that a resource group has the correct resources'
|
||||
|
||||
resource_group_name = ENV['AZURE_RESOURCE_GROUP_NAME']
|
||||
|
||||
describe azure_rg(name: resource_group_name) do
|
||||
its('total') { should be >= 7 }
|
||||
its('vm_count') { should eq 1 }
|
||||
end
|
||||
|
||||
describe azure_rg(name: resource_group_name).where { type == 'Microsoft.Storage/storageAccounts' }.entries do
|
||||
its('count') { should eq 1 }
|
||||
end
|
||||
|
||||
describe azure_rg(name: resource_group_name).contains(parameter: 'name', value: 'example-VM-ip') do
|
||||
it { should be true }
|
||||
end
|
||||
end
|
|
@ -17,3 +17,4 @@ control 'azure-vm-datadisks-1.0' do
|
|||
its('entries') { should_not be_empty }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
177
libraries/azure_rg.rb
Normal file
177
libraries/azure_rg.rb
Normal file
|
@ -0,0 +1,177 @@
|
|||
|
||||
require_relative 'common/helpers'
|
||||
|
||||
class AzureRg < Inspec.resource(1)
|
||||
|
||||
name 'azure_rg'
|
||||
|
||||
desc "
|
||||
This resource returns information about the specified resource group
|
||||
"
|
||||
|
||||
example "
|
||||
describe azure_rg(name: 'ACME') do
|
||||
its('nic_count') { should eq 4 }
|
||||
its('vm_count) { should eq 2 }
|
||||
end
|
||||
"
|
||||
|
||||
attr_reader :items, :rg, :counts
|
||||
|
||||
# Resource constructor
|
||||
#
|
||||
def initialize(opts)
|
||||
opts = opts
|
||||
helpers = Helpers.new
|
||||
|
||||
# Get the named resource group
|
||||
@rg = helpers.get_resource_group(opts[:name])
|
||||
|
||||
# Retrieve the items within the resource group
|
||||
rg_items = helpers.get_resources(opts[:name])
|
||||
|
||||
# Parse the resources
|
||||
@items = parse_rg_resources(rg_items.value)
|
||||
|
||||
end
|
||||
|
||||
# Create a FilterTable so that items can be selected
|
||||
filter = FilterTable.create
|
||||
filter.add_accessor(:where)
|
||||
.add_accessor(:entries)
|
||||
.add_accessor(:count)
|
||||
.add_accessor(:contains)
|
||||
.add(:type, field: 'type')
|
||||
.add(:name, field: 'name')
|
||||
.add(:location, field: 'location')
|
||||
|
||||
filter.connect(self, :items)
|
||||
|
||||
# Determine the location of the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# String
|
||||
#
|
||||
def location
|
||||
rg.location
|
||||
end
|
||||
|
||||
# Determime how many resources in total there are
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def total
|
||||
counts['total']
|
||||
end
|
||||
|
||||
# Determine how many of a certain type there are
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def count
|
||||
entries.length
|
||||
end
|
||||
|
||||
# Allows tests to be performed on the resources
|
||||
# For example it is possible to check that a resource of a certain name exists
|
||||
#
|
||||
# == Returns:
|
||||
# Boolean
|
||||
#
|
||||
def contains(settings)
|
||||
result = false
|
||||
|
||||
entries.each do |entry|
|
||||
if entry[settings[:parameter]] == settings[:value]
|
||||
result = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
# Helper method to determine the number of NICs in the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def nic_count
|
||||
counts['Microsoft.Network/networkInterfaces']
|
||||
end
|
||||
|
||||
# Helper method to determine the number of VMs in the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def vm_count
|
||||
counts['Microsoft.Compute/virtualMachines']
|
||||
end
|
||||
|
||||
# Helper method to determine the number of NSGs in the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def nsg_count
|
||||
counts['Microsoft.Network/networkSecurityGroups']
|
||||
end
|
||||
|
||||
# Helper method to determine the number of Virtual Networks in the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def vnet_count
|
||||
counts['Microsoft.Network/virtualNetworks']
|
||||
end
|
||||
|
||||
# Helper method to determine the number of Storage Accounts in the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def sa_count
|
||||
counts['Microsoft.Storage/storageAccounts']
|
||||
end
|
||||
|
||||
# Helper method to determine the number of Public IP Addresses in the resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Integer
|
||||
#
|
||||
def public_ip_count
|
||||
counts['Microsoft.Network/publicIPAddresses']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_rg_resources(resources)
|
||||
# Declare the hashtable of counts
|
||||
@counts = {
|
||||
'total' => 0,
|
||||
}
|
||||
|
||||
resources.each.map do |resource|
|
||||
parse_item(resource)
|
||||
end.compact
|
||||
end
|
||||
|
||||
def parse_item(item)
|
||||
# Increment the count total
|
||||
counts['total'] += 1
|
||||
|
||||
# Update the count for the resource type in the count table
|
||||
counts.key?(item.type) ? counts[item.type] +=1 : counts[item.type] = 1
|
||||
|
||||
{
|
||||
'location' => item.location,
|
||||
'name' => item.name,
|
||||
'type' => item.type,
|
||||
'new' => 'me',
|
||||
}
|
||||
end
|
||||
end
|
|
@ -59,7 +59,7 @@ class AzureVmDataDisks < Inspec.resource(1)
|
|||
# == Returns:
|
||||
# Boolean
|
||||
def has_disks?
|
||||
entries.!empty?
|
||||
!entries.empty?
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -5,19 +5,42 @@ require 'azure_mgmt_compute'
|
|||
require_relative 'resource_groups'
|
||||
|
||||
class Helpers
|
||||
# Retrieve the named virtual machine from Azure
|
||||
def get_vm(name, rg_name)
|
||||
# Azure connection
|
||||
azure = AzureConnection.new
|
||||
|
||||
client = Azure::ARM::Compute::ComputeManagementClient.new(azure.connection)
|
||||
attr_reader :azure, :client, :resource_group
|
||||
|
||||
def initialize
|
||||
# Azure connection
|
||||
@azure = AzureConnection.new
|
||||
|
||||
@client = Azure::ARM::Compute::ComputeManagementClient.new(azure.connection)
|
||||
client.subscription_id = azure.subscription_id
|
||||
|
||||
# Ensure that the resource group exists
|
||||
rg = ResourceGroups.new(azure)
|
||||
@resource_group = ResourceGroups.new(azure)
|
||||
end
|
||||
|
||||
unless rg.exists(rg_name)
|
||||
throw "The Resource group cannot be found: #{rg_name}"
|
||||
# Retrive the specified resource group
|
||||
#
|
||||
# == Returns:
|
||||
# Object representing the resource group
|
||||
#
|
||||
def get_resource_group(rg_name)
|
||||
resource_group.get(rg_name)
|
||||
end
|
||||
|
||||
def get_resources(rg_name)
|
||||
resource_group.get_resources(rg_name)
|
||||
end
|
||||
|
||||
# Retrieve the named virtual machine from Azure
|
||||
#
|
||||
# == Returns:
|
||||
# Object representing the VM in Azure
|
||||
#
|
||||
def get_vm(name, rg_name)
|
||||
|
||||
# Ensure that the resource group exists
|
||||
unless resource_group.exists(rg_name)
|
||||
raise "The Resource group cannot be found: #{rg_name}"
|
||||
end
|
||||
|
||||
# get a vm from the named resource group
|
||||
|
|
|
@ -2,12 +2,29 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class ResourceGroups
|
||||
|
||||
attr_reader :client
|
||||
|
||||
def initialize(azure)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(azure.connection)
|
||||
@client.subscription_id = azure.subscription_id
|
||||
client.subscription_id = azure.subscription_id
|
||||
end
|
||||
|
||||
def exists(name)
|
||||
@client.resource_groups.check_existence(name)
|
||||
client.resource_groups.check_existence(name)
|
||||
end
|
||||
|
||||
def get(name)
|
||||
|
||||
if exists(name)
|
||||
client.resource_groups.get(name)
|
||||
end
|
||||
end
|
||||
|
||||
def get_resources(name)
|
||||
|
||||
if exists(name)
|
||||
client.resource_groups.list_resources_as_lazy(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue