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

Improve resource not found #291

Merged
merged 5 commits into from
Sep 8, 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
9 changes: 9 additions & 0 deletions docs/resources/azure_generic_resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ The following parameters can be passed for targeting a specific Azure resource.
| resource_group | Azure resource group that the targeted resource has been created in. `MyResourceGroup` |
| name | Name of the Azure resource to test. `MyVM` |
| resource_provider | Azure resource provider of the resource to be tested. `Microsoft.Compute/virtualMachines` |
| resource_path | Relative path to the resource if it is defined on another resource. Resource path of a subnet in a virtual network would be: `{virtualNetworkName}/subnets`. |
| resource_id | Unique id of Azure resource to be tested. `/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{vmName}` |
| tag_name<superscript>*</superscript> | Tag name defined on the Azure resource. `name` |
| tag_value | Tag value of the tag defined with the `tag_name`. `external_linux` |
Expand All @@ -48,6 +49,7 @@ Either one of the parameter sets can be provided for a valid query:
- `resource_group` and `name`
- `name`
- `resource_group`, `resource_provider` and `name`
- `resource_group`, `resource_provider`, `resource_path` and `name`
- `tag_name` and `tag_value`

Different parameter combinations can be tried. If it is not supported either the InSpec resource or the Azure Rest API will raise an error.
Expand Down Expand Up @@ -101,6 +103,13 @@ describe azure_generic_resource(resource_group: 'my_vms', name: 'my_linux_vm') d
its('tags') { should include('name') } # regardless of the value
end
```
### Test Properties of a Virtual Machine Resides in an Azure Dev Test Lab
```ruby
describe azure_generic_resource(resource_provider: 'Microsoft.DevTestLab/labs', resource_path: '{labName}/virtualmachines', resource_group: 'my_group', name: 'my_VM') do
its('properties.userName') { should cmp 'admin' }
its('properties.allowClaim') { should cmp false }
end
```
For more examples, please see the [integration tests](/test/integration/verify/controls/azure_generic_resource.rb).

## Matchers
Expand Down
7 changes: 0 additions & 7 deletions libraries/azure_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -433,13 +433,6 @@ def catch_failed_resource_queries
resource_fail(message)
end

# Track the status of the resource at InSpec Azure resource pack level.
#
# @return [TrueClass, FalseClass] Whether the resource is failed or not.
def failed_resource?
@failed_resource ||= false
end

# Ensure required parameters have been set to perform backend operations.
#
# Some resources may require several parameters to be set, in which case use `required`.
Expand Down
15 changes: 14 additions & 1 deletion libraries/azure_generic_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ def initialize(opts = {}, static_resource = false)
#
# If there are static resource specific validations they can be passed here:
# required parameters via `opts[:required_parameters]`
validate_parameters(require_any_of: %i(resource_group name tag_name tag_value resource_id resource_provider))
validate_parameters(require_any_of: %i(resource_group
resource_path
name
tag_name
tag_value
resource_id
resource_provider))
end
@display_name = @opts.slice(:resource_group, :resource_provider, :name, :tag_name, :tag_value, :resource_id)
.values.join(' ')
Expand Down Expand Up @@ -131,4 +137,11 @@ def resource_group
res_group, _provider, _res_type = Helpers.res_group_provider_type_from_uri(id)
res_group
end

# Track the status of the resource at InSpec Azure resource pack level.
#
# @return [TrueClass, FalseClass] Whether the resource is failed or not.
def failed_resource?
@failed_resource ||= false
end
end
10 changes: 8 additions & 2 deletions libraries/azure_generic_resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ def to_s(class_name = nil)
end
end

# Return the InSpec level resource failure.
# This is a diversion from singular resources
# since an empty response from API should not be considered as failure.
# FilterTable will respond properly when it is an empty response.
def failed_resource?
resource_failed?
end

def api_version_used_for_query
@api_response[:api_version_used_for_query] if @api_response
end
Expand All @@ -110,8 +118,6 @@ def api_version_used_for_query_state
# @param table_scheme [Array] [{column: :blahs, field: :blah}, {..}]
def self.populate_filter_table(raw_data, table_scheme)
filter_table = FilterTable.create
# puts "Table scheme in pop fil met #{table_scheme}"
# puts "Raw data: #{raw_data}"
table_scheme.each do |col_field|
filter_table.register_column(col_field[:column], field: col_field[:field])
end
Expand Down
7 changes: 7 additions & 0 deletions libraries/azure_graph_generic_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,11 @@ def to_s(class_name = nil)
"#{class_name.name.split('_').map(&:capitalize).join(' ')} #{api_info}: #{@display_name}"
end
end

# Track the status of the resource at InSpec Azure resource pack level.
#
# @return [TrueClass, FalseClass] Whether the resource is failed or not.
def failed_resource?
@failed_resource ||= false
end
end
8 changes: 8 additions & 0 deletions libraries/azure_graph_generic_resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,12 @@ def self.populate_filter_table(raw_data, table_scheme)
end
filter_table.install_filter_methods_on_resource(self, raw_data)
end

# Return the InSpec level resource failure.
# This is a diversion from singular resources
# since an empty response from API should not be considered as failure.
# FilterTable will respond properly when it is an empty response.
def failed_resource?
resource_failed?
end
end
2 changes: 1 addition & 1 deletion libraries/azure_virtual_machines.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def to_s
def populate_table
# If @resources empty than @table should stay as an empty array as declared in superclass.
# This will ensure constructing resource and passing `should_not exist` test.
return if @resources.empty?
return [] if @resources.empty?
@resources.each do |resource|
os_profile = resource[:properties][:osProfile]
platform = \
Expand Down
3 changes: 3 additions & 0 deletions libraries/backend/azure_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ def fail_api_query(resp, message = nil)
raise UnsuccessfulAPIQuery::ResourceNotFound, error_message
end
end
if resource_not_found_codes.include?(body[:httpStatusCode])
raise UnsuccessfulAPIQuery::ResourceNotFound, message
end
raise UnsuccessfulAPIQuery::UnexpectedHTTPResponse, message
end
end
2 changes: 1 addition & 1 deletion terraform/azure.tf
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ resource "azurerm_eventhub_authorization_rule" "auth_rule_inspectesteh" {
}

resource "azurerm_iothub" "iothub" {
name = "inspectest-iothub"
name = "inspectest-iothub-${random_string.event_hub.result}"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
sku {
Expand Down