Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def initialize(ems_event)
@ems_event = ems_event
end

# Parses all targets present in the EmsEvent givin in the initializer
# Parses all targets present in the EmsEvent given in the initializer
# @return [Array] Array of InventoryRefresh::Target objects
def parse
parse_ems_event_targets(ems_event)
Expand All @@ -24,23 +24,23 @@ def parse_ems_event_targets(ems_event)
# there's almost always a tenant id regardless of event type
collect_identity_tenant_references!(target_collection)

target_type = if ems_event.event_type.start_with?("floatingip.")
target_type = case resource_type
when "floatingip"
:floating_ips
elsif ems_event.event_type.start_with?("router.")
when "router"
:network_routers
elsif ems_event.event_type.start_with?("port.")
when "port"
:network_ports
elsif ems_event.event_type.start_with?("network.")
when "network"
:cloud_networks
elsif ems_event.event_type.start_with?("subnet.")
when "subnet"
:cloud_subnets
elsif ems_event.event_type.start_with?("security_group.")
when "security_group"
:security_groups
elsif ems_event.event_type.start_with?("security_group_rule.")
when "security_group_rule"
:firewall_rules
end

resource_id = event_payload['resource_id']
if resource_id
add_target(target_collection, target_type, resource_id)
elsif target_type == :security_groups
Expand All @@ -58,7 +58,12 @@ def parse_ems_event_targets(ems_event)
end

def collect_identity_tenant_references!(target_collection)
tenant_id = event_payload['tenant_id'] || event_payload['project_id'] || event_payload.fetch_path('initiator', 'project_id')
tenant_id = event_payload['tenant_id'] ||
event_payload['project_id'] ||
event_payload.dig(resource_type, 'tenant_id') ||
event_payload.dig(resource_type, 'project_id') ||
event_payload.dig('initiator', 'project_id')

add_target(target_collection, :cloud_tenants, tenant_id) if tenant_id
end

Expand All @@ -73,4 +78,12 @@ def add_target(target_collection, association, ref)
def event_payload
@event_payload ||= ManageIQ::Providers::Openstack::EventParserCommon.message_content(ems_event).fetch('payload', {})
end
end

def resource_type
@resource_type ||= ems_event.event_type.split(".").first
end

def resource_id
@resource_id ||= event_payload.dig(resource_type, "id") || event_payload["resource_id"]
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -13,98 +13,204 @@
oslo_message_text = "with#{"out" unless oslo_message} oslo_message"

it "parses network events #{oslo_message_text}" do
payload = {"resource_id" => "network_id_test"}
payload = {
"network" => {
"id" => "network_id_test",
"name" => "test_network",
"tenant_id" => "tenant_id_test",
"project_id" => "tenant_id_test"
}
}
ems_event = create_ems_event(@manager, "network.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(parsed_targets.size).to eq(2) # network + tenant
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_tenants, {:ems_ref => "tenant_id_test"}],
[:cloud_networks, {:ems_ref => "network_id_test"}]
]
)
)
end

it "parses subnet events #{oslo_message_text}" do
payload = {"resource_id" => "subnet_id_test"}
payload = {
"subnet" => {
"id" => "subnet_id_test",
"name" => "test_subnet",
"tenant_id" => "tenant_id_test",
"project_id" => "tenant_id_test",
"network_id" => "network_id_test"
}
}
ems_event = create_ems_event(@manager, "subnet.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(parsed_targets.size).to eq(2) # subnet + tenant
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_tenants, {:ems_ref => "tenant_id_test"}],
[:cloud_subnets, {:ems_ref => "subnet_id_test"}]
]
)
)
end

it "parses router events #{oslo_message_text}" do
payload = {"resource_id" => "router_id_test"}
payload = {
"router" => {
"id" => "router_id_test",
"name" => "test_router",
"tenant_id" => "tenant_id_test",
"project_id" => "tenant_id_test"
}
}
ems_event = create_ems_event(@manager, "router.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(parsed_targets.size).to eq(2) # router + tenant
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_tenants, {:ems_ref => "tenant_id_test"}],
[:network_routers, {:ems_ref => "router_id_test"}]
]
)
)
end

it "parses port events #{oslo_message_text}" do
payload = {"resource_id" => "port_id_test"}
payload = {
"port" => {
"id" => "port_id_test",
"name" => "test_port",
"tenant_id" => "tenant_id_test",
"project_id" => "tenant_id_test",
"network_id" => "network_id_test"
}
}
ems_event = create_ems_event(@manager, "port.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(parsed_targets.size).to eq(2) # port + tenant
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_tenants, {:ems_ref => "tenant_id_test"}],
[:network_ports, {:ems_ref => "port_id_test"}]
]
)
)
end

it "parses floating ip events #{oslo_message_text}" do
payload = {"resource_id" => "floating_ip_id_test"}
payload = {
"floatingip" => {
"id" => "floating_ip_id_test",
"floating_ip_address" => "192.168.1.100",
"tenant_id" => "tenant_id_test",
"project_id" => "tenant_id_test"
}
}
ems_event = create_ems_event(@manager, "floatingip.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(parsed_targets.size).to eq(2) # floating_ip + tenant
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_tenants, {:ems_ref => "tenant_id_test"}],
[:floating_ips, {:ems_ref => "floating_ip_id_test"}]
]
)
)
end

it "parses security_group events #{oslo_message_text}" do
payload = {"resource_id" => "security_group_id_test"}
payload = {
"security_group" => {
"id" => "security_group_id_test",
"name" => "test_security_group",
"tenant_id" => "tenant_id_test",
"project_id" => "tenant_id_test"
}
}
ems_event = create_ems_event(@manager, "security_group.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(parsed_targets.size).to eq(2) # security_group + tenant
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_tenants, {:ems_ref => "tenant_id_test"}],
[:security_groups, {:ems_ref => "security_group_id_test"}]
]
)
)
end

it "parses security_group_rule events without ID #{oslo_message_text}" do
payload = {
"security_group_rule" => {
"ethertype" => "IPv4",
"direction" => "ingress",
"security_group_id" => "security_group_id_test",
"protocol" => "tcp"
}
}
ems_event = create_ems_event(@manager, "security_group_rule.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1) # firewall_rules with nil (full refresh)
expect(target_references(parsed_targets)).to(
match_array(
[
[:firewall_rules, {:ems_ref => nil}]
]
)
)
end

it "falls back to direct resource_id field when nested structure not present #{oslo_message_text}" do
payload = {"resource_id" => "network_id_test"}
ems_event = create_ems_event(@manager, "network.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(1)
expect(target_references(parsed_targets)).to(
match_array(
[
[:cloud_networks, {:ems_ref => "network_id_test"}]
]
)
)
end

it "extracts tenant_id from initiator when not in resource #{oslo_message_text}" do
payload = {
"network" => {
"id" => "network_id_test",
"name" => "test_network"
},
"initiator" => {
"project_id" => "initiator_tenant_id"
}
}
ems_event = create_ems_event(@manager, "network.create.end", oslo_message, payload)

parsed_targets = described_class.new(ems_event).parse
expect(parsed_targets.size).to eq(2)
expect(target_references(parsed_targets)).to(
include([:cloud_tenants, {:ems_ref => "initiator_tenant_id"}])
)
end
end
end

def target_references(parsed_targets)
parsed_targets.map { |x| [x.association, x.manager_ref] }.uniq
end
end
end