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:
Russell Seymour 2017-02-20 13:51:41 +00:00
parent c2bc6dc40d
commit 7a6cbff579
7 changed files with 296 additions and 17 deletions

View file

@ -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
View 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

View file

@ -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
View 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

View file

@ -59,7 +59,7 @@ class AzureVmDataDisks < Inspec.resource(1)
# == Returns:
# Boolean
def has_disks?
entries.!empty?
!entries.empty?
end
private

View file

@ -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

View file

@ -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