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

Include AWS resource name in code description in AWS Config Mapper #115

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
55 changes: 51 additions & 4 deletions lib/heimdall_tools/aws_config_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,26 @@ def fetch_all_compliance_info(config_rules)
#
# Returns: The same config_rules array with `results` key added to each rule.
def add_results_to_config_rules(config_rules)
resource_name_map = {}
config_rules.each do |rule|
response = @client.get_compliance_details_by_config_rule(config_rule_name: rule[:config_rule_name], limit: 100)
rule_results = response.to_h[:evaluation_results]
while response.next_token
response = @client.get_compliance_details_by_config_rule(next_token: response.next_token, limit: 100)
response = @client.get_compliance_details_by_config_rule(config_rule_name: rule[:config_rule_name], next_token: response.next_token, limit: 100)
rule_results += response.to_h[:evaluation_results]
end

resource_name_map = get_resource_name_map(rule_results, resource_name_map)

rule[:results] = []
rule_results.each do |result|
hdf_result = {}
# code_desc
hdf_result['code_desc'] = result.dig(:evaluation_result_identifier, :evaluation_result_qualifier)&.map do |k, v|
"#{k}: #{v}"
end&.join(', ')
code_desc = result.dig(:evaluation_result_identifier, :evaluation_result_qualifier)&.map do |k, v|
"#{k}: #{v}"
end&.join(', ') || ''
code_desc += ", resource_name: #{resource_name_map[result.dig(:evaluation_result_identifier, :evaluation_result_qualifier, :resource_id)] || 'unknown'}"
hdf_result['code_desc'] = code_desc
# start_time
hdf_result['start_time'] = if result.key?(:config_rule_invoked_time)
DateTime.parse(result[:config_rule_invoked_time].to_s).strftime('%Y-%m-%dT%H:%M:%S%:z')
Expand Down Expand Up @@ -246,6 +251,48 @@ def add_results_to_config_rules(config_rules)
config_rules
end

##
# Takes in `rule_results` from a `get_compliance_details_by_config_rule` API call,
# then makes `list_discovered_resources` API calls to get the `resource_name` for
# each resouce ID.
#
# Resource ID alone without resource name commonly makes it inconvenient to figure out
# what AWS resource that the rule is referencing in its results.
def get_resource_name_map(rule_results, current_resource_name_map)
# Should be in the format: { resource_id: resource_name }
resource_map = {}

# Group by resource Type because the API call requires a type to be specified
groups = rule_results.group_by { |e| e.dig(:evaluation_result_identifier, :evaluation_result_qualifier, :resource_type) }
# Trim down values to just the ids
groups = groups.map do |resource_type, rule_results_arr|
[
resource_type,
rule_results_arr.map { |result| result.dig(:evaluation_result_identifier, :evaluation_result_qualifier, :resource_id) }.uniq,
]
end
# Reject any ids that are already in `current_resource_name_map`
groups = groups.map do |resource_type, resource_ids|
[
resource_type,
resource_ids.reject { |id| current_resource_name_map.include? id },
]
end

groups.each do |resource_type, resource_ids|
# API endpoint reports a max size of 20
resource_ids.each_slice(20) do |resource_ids_slice|
# Don't send an API call for an empty array
next if resource_ids_slice.empty?

response = @client.list_discovered_resources(resource_type: resource_type, resource_ids: resource_ids_slice, limit: 100)
resource_map = resource_map.merge(response.resource_identifiers.map { |resource| [resource.resource_id, resource.resource_name] }.to_h)
end
end

current_resource_name_map.merge resource_map
end

##
# Takes in a config rule and pulls out tags that are useful for HDF.
#
Expand Down