ManageIQ/manageiq-providers-amazon

View on GitHub
app/models/manageiq/providers/amazon/cloud_manager/event_target_parser.rb

Summary

Maintainability
A
3 hrs
Test Coverage
A
98%
class ManageIQ::Providers::Amazon::CloudManager::EventTargetParser
attr_reader :ems_event
 
# @param ems_event [EmsEvent] EmsEvent object
def initialize(ems_event)
@ems_event = ems_event
end
 
# Parses all targets that are present in the EmsEvent given in the initializer
#
# @return [Array] Array of InventoryRefresh::Target objects
def parse
parse_ems_event_targets(ems_event)
end
 
private
 
# Parses list of InventoryRefresh::Target out of the given EmsEvent
#
# @param event [EmsEvent] EmsEvent object
# @return [Array] Array of InventoryRefresh::Target objects
def parse_ems_event_targets(event)
target_collection = InventoryRefresh::TargetCollection.new(:manager => event.ext_management_system, :event => event)
 
case event.full_data["event_source"]
when :cloud_watch_api
collect_cloudwatch_api_references!(target_collection,
event.full_data.fetch_path("detail", "requestParameters") || {})
collect_cloudwatch_api_references!(target_collection,
event.full_data.fetch_path("detail", "responseElements") || {})
when :cloud_watch_ec2
collect_cloudwatch_ec2_references!(target_collection, event.full_data)
when :cloud_watch_ec2_ebs_snapshot
collect_cloudwatch_ec2_ebs_snapshot_references!(target_collection, event.full_data)
when :config
collect_config_references!(target_collection, event.full_data)
end
 
target_collection.targets
end
 
def parsed_targets(target_collection = {})
target_collection.select { |_target_class, references| references[:manager_ref].present? }
end
 
def add_target(target_collection, association, ref)
target_collection.add_target(:association => association, :manager_ref => {:ems_ref => ref}) unless ref.blank?
end
 
def add_name_target(target_collection, association, ref)
target_collection.add_target(:association => association, :manager_ref => {:name => ref}) unless ref.blank?
end
 
def collect_cloudwatch_ec2_references!(target_collection, event_data)
instance_id = event_data.fetch_path("detail", "instance-id")
add_target(target_collection, :vms, instance_id) if instance_id
end
 
def collect_cloudwatch_ec2_ebs_snapshot_references!(target_collection, event_data)
if (snapshot_id = event_data.fetch_path('detail', 'snapshot_id'))
add_target(target_collection, :cloud_volume_snapshots, snapshot_id.split('/').last)
end
end
 
def collect_config_references!(target_collection, event_data)
resource_type = event_data.fetch_path("configurationItem", "resourceType")
resource_id = event_data.fetch_path("configurationItem", "resourceId")
target_class = case resource_type
when "AWS::EC2::Instance"
:vms
when "AWS::EC2::SecurityGroup"
:security_groups
when "AWS::EC2::Volume"
:cloud_volumes
when "AWS::EC2::NetworkInterface"
:network_ports
when "AWS::EC2::VPC"
:cloud_networks
when "AWS::EC2::Subnet"
:cloud_subnets
when "AWS::EC2::EIP"
:floating_ips
when "AWS::CloudFormation::Stack"
:orchestration_stacks
end
 
add_target(target_collection, target_class, resource_id) if target_class && resource_id
end
 
Cyclomatic complexity for collect_cloudwatch_api_references! is too high. [31/11]
Method `collect_cloudwatch_api_references!` has a Cognitive Complexity of 28 (exceeds 11 allowed). Consider refactoring.
def collect_cloudwatch_api_references!(target_collection, event_data, depth = 0)
# Check a reasonable depth, so this can't fail with max stack size
raise "Depth 20 reached when scanning EmsEvent for Targets" if depth > 20
 
# Cloud
add_target(target_collection, :vms, event_data["instanceId"]) if event_data["instanceId"]
add_target(target_collection, :miq_templates, event_data["imageId"]) if event_data["imageId"]
add_name_target(target_collection, :key_pairs, event_data["keyName"]) if event_data["keyName"]
add_target(target_collection, :orchestration_stacks, event_data["stackId"]) if event_data["stackId"]
add_target(target_collection, :orchestration_stacks, event_data["stackName"]) if event_data["stackName"]
# Network
add_target(target_collection, :cloud_networks, event_data["vpcId"]) if event_data["vpcId"]
add_target(target_collection, :cloud_networks, event_data.fetch_path("vpc", "vpcId")) if event_data.fetch_path("vpc", "vpcId")
if event_data.fetch_path("EnableVpcClassicLinkDnsSupportRequest", "VpcId")
add_target(target_collection, :cloud_networks, event_data.fetch_path("EnableVpcClassicLinkDnsSupportRequest", "VpcId"))
end
add_target(target_collection, :cloud_subnets, event_data["subnetId"]) if event_data["subnetId"]
add_target(target_collection, :network_ports, event_data["networkInterfaceId"]) if event_data["networkInterfaceId"]
add_target(target_collection, :security_groups, event_data["groupId"]) if event_data["groupId"]
add_target(target_collection, :floating_ips, event_data["allocationId"]) if event_data["allocationId"]
add_target(target_collection, :floating_ips, event_data["publicIp"]) if event_data["publicIp"]
add_target(target_collection, :load_balancers, event_data["loadBalancerName"]) if event_data["loadBalancerName"]
# Block Storage
 
volume_id = event_data["volumeId"] || event_data.dig("ModifyVolumeResponse", "volumeModification", "volumeId")
add_target(target_collection, :cloud_volumes, volume_id) if volume_id
 
add_target(target_collection, :cloud_volume_snapshots, event_data["snapshotId"]) if event_data["snapshotId"]
 
# Service Catalog
add_target(target_collection, :service_offerings, event_data["productId"]) if event_data["productId"]
add_target(target_collection, :service_instances, event_data["provisionedProductId"]) if event_data["provisionedProductId"]
 
# TODO(lsmola) how to handle tagging? Tagging affects e.g. a name of any resource, but contains only a generic
# resourceID
# "requestParameters"=>
# {"resourcesSet"=>{"items"=>[{"resourceId"=>"vol-07ad036724e3175a5"}]},
# "tagSet"=>{"items"=>[{"key"=>"Name", "value"=>"ladas_volue_2"}]}},
# I think we can parse the resource id, so guess where it belongs.
# TODO(lsmola) RegisterImage, by creating image from a volume snapshot, should we track the block device
# mapping and refresh also snapshot?
 
# Collect nested references
collect_cloudwatch_api_references!(target_collection, event_data["networkInterface"], depth + 1) if event_data["networkInterface"]
collect_cloudwatch_api_references!(target_collection, event_data["recordDetail"], depth + 1) if event_data["recordDetail"]
 
(event_data.fetch_path("groupSet", "items") || []).each do |x|
collect_cloudwatch_api_references!(target_collection, x, depth + 1)
end
(event_data.fetch_path("instancesSet", "items") || []).each do |x|
collect_cloudwatch_api_references!(target_collection, x, depth + 1)
end
(event_data.fetch_path("instances") || []).each do |x|
collect_cloudwatch_api_references!(target_collection, x, depth + 1)
end
(event_data.fetch_path("networkInterfaceSet", "items") || []).each do |x|
collect_cloudwatch_api_references!(target_collection, x, depth + 1)
end
end
end