mirror of
https://github.com/inspec/inspec
synced 2024-12-24 20:13:16 +00:00
a5309ea392
Signed-off-by: Ryan Davis <zenspider@chef.io>
262 lines
7.6 KiB
Ruby
262 lines
7.6 KiB
Ruby
require "resources/azure/azure_backend"
|
|
|
|
module Inspec::Resources
|
|
class AzureVirtualMachine < AzureResourceBase
|
|
name "azure_virtual_machine"
|
|
|
|
desc '
|
|
InSpec Resource to test Azure Virtual Machines
|
|
'
|
|
|
|
supports platform: "azure"
|
|
|
|
# Constructor for the resource. This calls the parent constructor to
|
|
# get the generic resource for the specified machine. This will provide
|
|
# static methods that are documented
|
|
#
|
|
# @author Russell Seymour
|
|
def initialize(opts = {})
|
|
# The generic resource needs to pass back a Microsoft.Compute/virtualMachines object so force it
|
|
opts[:type] = "Microsoft.Compute/virtualMachines"
|
|
super(opts)
|
|
|
|
# Find the virtual machines
|
|
resources
|
|
|
|
create_tag_methods
|
|
end
|
|
|
|
# Method to catch calls that are not explicitly defined.
|
|
# This allows the simple attributes of the virtual machine to be read without having
|
|
# to define each one in turn.
|
|
#
|
|
# rubocop:disable Metrics/AbcSize
|
|
#
|
|
# @param symobl method_id The symbol of the method that has been called
|
|
#
|
|
# @return Value of attribute that has been called
|
|
def method_missing(method_id)
|
|
# Depending on the method that has been called, determine what value should be returned
|
|
# These are set as camel case methods to comply with rubocop
|
|
image_reference_attrs = %w{sku publisher offer}
|
|
osdisk_attrs = %w{os_type caching create_option disk_size_gb}
|
|
hardware_profile_attrs = %w{vm_size}
|
|
os_profile_attrs = %w{computer_name admin_username}
|
|
osdisk_managed_disk_attrs = %w{storage_account_type}
|
|
|
|
# determine the method name to call by converting the snake_case to camelCase
|
|
# method_name = self.camel_case(method_id.to_s)
|
|
method_name = method_id.to_s.split("_").inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
|
method_name.end_with?("Gb") ? method_name.gsub!(/Gb/, &:upcase) : false
|
|
|
|
if image_reference_attrs.include?(method_id.to_s)
|
|
properties.storageProfile.imageReference.send(method_name)
|
|
elsif osdisk_attrs.include?(method_id.to_s)
|
|
properties.storageProfile.osDisk.send(method_name)
|
|
elsif hardware_profile_attrs.include?(method_id.to_s)
|
|
properties.hardwareProfile.send(method_name)
|
|
elsif os_profile_attrs.include?(method_id.to_s)
|
|
properties.osProfile.send(method_name)
|
|
elsif osdisk_managed_disk_attrs.include?(method_id.to_s)
|
|
properties.storageProfile.osDisk.managedDisk.send(method_name)
|
|
end
|
|
end
|
|
|
|
# Return the name of the os disk
|
|
#
|
|
# @return string Name of the OS disk
|
|
def os_disk_name
|
|
properties.storageProfile.osDisk.name
|
|
end
|
|
|
|
# Determine if the OS disk is a managed disk
|
|
#
|
|
# @return boolean
|
|
def has_managed_osdisk?
|
|
defined?(properties.storageProfile.osDisk.managedDisk)
|
|
end
|
|
|
|
# Does the machine have any NICs connected
|
|
#
|
|
# @return boolean
|
|
def has_nics?
|
|
properties.networkProfile.networkInterfaces.count != 0
|
|
end
|
|
|
|
# How many NICs are connected to the machine
|
|
#
|
|
# @return integer
|
|
def nic_count
|
|
properties.networkProfile.networkInterfaces.count
|
|
end
|
|
|
|
# Return an array of the connected NICs so that it can be tested to ensure
|
|
# the machine is connected properly
|
|
#
|
|
# @return array Array of NIC names connected to the machine
|
|
def connected_nics
|
|
nic_names = []
|
|
properties.networkProfile.networkInterfaces.each do |nic|
|
|
nic_names << nic.id.split(%r{/}).last
|
|
end
|
|
nic_names
|
|
end
|
|
|
|
# Whether the machine has data disks or not
|
|
#
|
|
# @return boolean
|
|
def has_data_disks?
|
|
properties.storageProfile.dataDisks.count != 0
|
|
end
|
|
|
|
# How many data disks are connected
|
|
#
|
|
# @return integer
|
|
def data_disk_count
|
|
properties.storageProfile.dataDisks.count
|
|
end
|
|
|
|
# Does the machine allow password authentication
|
|
#
|
|
# This allows the use of
|
|
# it { should have_password_authentication }
|
|
# within the InSpec profile
|
|
#
|
|
# @return boolean
|
|
def has_password_authentication?
|
|
password_authentication?
|
|
end
|
|
|
|
# Deteremine if the machine allows password authentication
|
|
#
|
|
# @return boolean
|
|
def password_authentication?
|
|
# if the osProfile property has a linuxConfiguration section then interrogate that
|
|
# otherwise it is a Windows machine and that always has password auth
|
|
if defined?(properties.osProfile.linuxConfiguration)
|
|
!properties.osProfile.linuxConfiguration.disablePasswordAuthentication
|
|
else
|
|
true
|
|
end
|
|
end
|
|
|
|
# Has the machine been given Custom Data at creation
|
|
#
|
|
# This allows the use of
|
|
# it { should have_custom_data }
|
|
# within the InSpec Profile
|
|
#
|
|
# @return boolean
|
|
def has_custom_data?
|
|
custom_data?
|
|
end
|
|
|
|
# Determine if custom data has been set
|
|
#
|
|
# @return boolean
|
|
def custom_data?
|
|
if defined?(properties.osProfile.CustomData)
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
# Are any SSH Keys assigned to the machine
|
|
#
|
|
# This allows the use of
|
|
# it { should have_ssh_keys }
|
|
# within the InSpec Profile
|
|
#
|
|
# @return boolean
|
|
def has_ssh_keys?
|
|
ssh_keys?
|
|
end
|
|
|
|
# Determine if any ssh keys have been asigned to the machine
|
|
#
|
|
# @return boolean
|
|
def ssh_keys?
|
|
if defined?(properties.osProfile.linuxConfiguration.ssh)
|
|
properties.osProfile.linuxConfiguration.ssh.publicKeys != 0
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
# Return the number of ssh keys that have been assigned to the machine
|
|
#
|
|
# @return integer
|
|
def ssh_key_count
|
|
if defined?(properties.osProfile.linuxConfiguration.ssh)
|
|
properties.osProfile.linuxConfiguration.ssh.publicKeys.count
|
|
else
|
|
0
|
|
end
|
|
end
|
|
|
|
# Determine is the specified key is in the ssh_keys list
|
|
#
|
|
# @return array Array of the public keys that are assigned to allow for testing of that key
|
|
def ssh_keys
|
|
# iterate around the keys
|
|
keys = []
|
|
properties.osProfile.linuxConfiguration.ssh.publicKeys.each do |key|
|
|
keys << key.keyData
|
|
end
|
|
keys
|
|
end
|
|
|
|
# Does the machine have boot diagnostics enabled
|
|
#
|
|
# @return boolean
|
|
def has_boot_diagnostics?
|
|
if defined?(properties.diagnosticsProfile)
|
|
properties.diagnosticsProfile.bootDiagnostics.enabled
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
# Return the URI that has been set for the boot diagnostics storage
|
|
#
|
|
# @return string
|
|
def boot_diagnostics_storage_uri
|
|
properties.diagnosticsProfile.bootDiagnostics.storageUri
|
|
end
|
|
|
|
# If this is a windows machine, returns whether the agent was provisioned or not
|
|
#
|
|
# @return boolean
|
|
def has_provision_vmagent?
|
|
if defined?(properties.osProfile.windowsConfiguration)
|
|
properties.osProfile.windowsConfiguration.provisionVMAgent
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
# If a windows machine see if automatic updates for the agent are enabled
|
|
#
|
|
# @return boolean
|
|
def has_automatic_agent_update?
|
|
if defined?(properties.osProfile.windowsConfiguration)
|
|
properties.osProfile.windowsConfiguration.enableAutomaticUpdates
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
# If this is a windows machine return a boolean to state of the WinRM options
|
|
# have been set
|
|
#
|
|
# @return boolean
|
|
def has_winrm_options?
|
|
if defined?(properties.osProfile.windowsConfiguration) && defined?(properties.osProfile.windowsConfiguration.winrm)
|
|
properties.osProfile.windowsConfiguration.winrm.protocol
|
|
else
|
|
false
|
|
end
|
|
end
|
|
end
|
|
end
|