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

Trigger software updates process in event handler #2506

Closed
Closed
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
4 changes: 3 additions & 1 deletion lib/trento/event_handlers_supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule Trento.EventHandlersSupervisor do
alias Trento.Infrastructure.Commanded.EventHandlers.{
AlertsEventHandler,
RollUpEventHandler,
SoftwareUpdatesDiscoveryEventHandler,
StreamRollUpEventHandler
}

Expand All @@ -18,7 +19,8 @@ defmodule Trento.EventHandlersSupervisor do
children = [
AlertsEventHandler,
RollUpEventHandler,
StreamRollUpEventHandler
StreamRollUpEventHandler,
SoftwareUpdatesDiscoveryEventHandler
]

Supervisor.init(children, strategy: :one_for_one)
Expand Down
13 changes: 0 additions & 13 deletions lib/trento/hosts/commands/discover_software_updates.ex

This file was deleted.

12 changes: 0 additions & 12 deletions lib/trento/hosts/events/software_updates_discovery_requested.ex

This file was deleted.

19 changes: 1 addition & 18 deletions lib/trento/hosts/host.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ defmodule Trento.Hosts.Host do
CompleteHostChecksExecution,
CompleteSoftwareUpdatesDiscovery,
DeregisterHost,
DiscoverSoftwareUpdates,
RegisterHost,
RequestHostDeregistration,
RollUpHost,
Expand Down Expand Up @@ -106,8 +105,7 @@ defmodule Trento.Hosts.Host do
SaptuneStatusUpdated,
SlesSubscriptionsUpdated,
SoftwareUpdatesDiscoveryCleared,
SoftwareUpdatesDiscoveryCompleted,
SoftwareUpdatesDiscoveryRequested
SoftwareUpdatesDiscoveryCompleted
}

@required_fields []
Expand Down Expand Up @@ -538,19 +536,6 @@ defmodule Trento.Hosts.Host do

# Software Updates Discovery

def execute(
%Host{
host_id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
},
%DiscoverSoftwareUpdates{}
) do
%SoftwareUpdatesDiscoveryRequested{
host_id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
}
end

def execute(
%Host{host_id: host_id} = host,
%CompleteSoftwareUpdatesDiscovery{
Expand Down Expand Up @@ -737,8 +722,6 @@ defmodule Trento.Hosts.Host do
}
end

def apply(%Host{} = host, %SoftwareUpdatesDiscoveryRequested{}), do: host

def apply(
%Host{} = host,
%SoftwareUpdatesDiscoveryCompleted{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
defmodule Trento.Infrastructure.Commanded.EventHandlers.SoftwareUpdatesDiscoveryEventHandler do
@moduledoc """
Event handler for software updates discovery related events.

It triggers the process of discovering software updates for a host when:
- a host gets registered
- the fqdn of a host changes
- when a host gets restored after being deregistered
"""

use Commanded.Event.Handler,
application: Trento.Commanded,
name: "software_updates_discovery_event_handler"

require Logger

alias Trento.Hosts.Events.{
HostDetailsUpdated,
HostRegistered,
HostRestored
}

alias Trento.Hosts
alias Trento.Hosts.Projections.HostReadModel
alias Trento.SoftwareUpdates.Discovery

def handle(
%HostRegistered{
host_id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
},
_
)
when not is_nil(fully_qualified_domain_name) do
Discovery.discover_host_software_updates(host_id, fully_qualified_domain_name)
:ok
end

def handle(%HostRestored{host_id: host_id}, _) do
case Hosts.get_host_by_id(host_id) do
%HostReadModel{id: host_id, fully_qualified_domain_name: fully_qualified_domain_name} ->
Discovery.discover_host_software_updates(host_id, fully_qualified_domain_name)

nil ->
Logger.error("Host not found: #{host_id}")
end

:ok
end

def handle(
%HostDetailsUpdated{
host_id: host_id,
fully_qualified_domain_name: new_fully_qualified_domain_name
},
_
) do
case Hosts.get_host_by_id(host_id) do
%HostReadModel{
id: host_id,
fully_qualified_domain_name: current_fully_qualified_domain_name
} ->
discover_or_clear_software_updates(
host_id,
current_fully_qualified_domain_name,
new_fully_qualified_domain_name
)

nil ->
Logger.error("Host not found: #{host_id}")
end

:ok
end

defp discover_or_clear_software_updates(
host_id,
current_fully_qualified_domain_name,
new_fully_qualified_domain_name
)
when current_fully_qualified_domain_name != new_fully_qualified_domain_name and
is_nil(new_fully_qualified_domain_name),
do: Discovery.clear_host_software_updates_discovery(host_id)

defp discover_or_clear_software_updates(
host_id,
current_fully_qualified_domain_name,
new_fully_qualified_domain_name
)
when current_fully_qualified_domain_name != new_fully_qualified_domain_name,
do: Discovery.discover_host_software_updates(host_id, new_fully_qualified_domain_name)

defp discover_or_clear_software_updates(_, _, _), do: nil
end
2 changes: 0 additions & 2 deletions lib/trento/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ defmodule Trento.Router do
CompleteHostChecksExecution,
CompleteSoftwareUpdatesDiscovery,
DeregisterHost,
DiscoverSoftwareUpdates,
RegisterHost,
RequestHostDeregistration,
RollUpHost,
Expand Down Expand Up @@ -56,7 +55,6 @@ defmodule Trento.Router do
RequestHostDeregistration,
DeregisterHost,
CompleteHostChecksExecution,
DiscoverSoftwareUpdates,
CompleteSoftwareUpdatesDiscovery,
ClearSoftwareUpdatesDiscovery
],
Expand Down
40 changes: 25 additions & 15 deletions lib/trento/software_updates/discovery.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ defmodule Trento.SoftwareUpdates.Discovery do
do:
{:ok,
Hosts.get_all_hosts()
|> Enum.map(&discover_host_software_updates/1)
|> Enum.map(fn %HostReadModel{
id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
} ->
discover_host_software_updates(host_id, fully_qualified_domain_name)
end)
|> Enum.split_with(fn
{:ok, _, _, _} -> true
_ -> false
Expand All @@ -52,12 +57,8 @@ defmodule Trento.SoftwareUpdates.Discovery do
hosts = Hosts.get_all_hosts()

hosts
|> Enum.map(fn %HostReadModel{id: host_id} -> %{host_id: host_id} end)
|> Enum.each(fn command_payload ->
command_payload
|> ClearSoftwareUpdatesDiscovery.new!()
|> commanded().dispatch()
end)
|> Enum.map(fn %HostReadModel{id: host_id} -> host_id end)
|> Enum.each(&clear_host_software_updates_discovery/1)

if !Enum.empty?(hosts) do
clear()
Expand All @@ -66,18 +67,27 @@ defmodule Trento.SoftwareUpdates.Discovery do
:ok
end

defp discover_host_software_updates(%HostReadModel{
id: host_id,
fully_qualified_domain_name: nil
}) do
def clear_host_software_updates_discovery(host_id),
do:
%{host_id: host_id}
|> ClearSoftwareUpdatesDiscovery.new!()
|> commanded().dispatch()

@spec discover_host_software_updates(String.t(), String.t()) ::
{:ok, any()} | {:error, any(), any()}
def discover_host_software_updates(host_id, fully_qualified_domain_name)
when is_nil(fully_qualified_domain_name) do
Logger.info("Host #{host_id} does not have an fqdn. Skipping software updates discovery")
{:error, host_id, :host_without_fqdn}
end

defp discover_host_software_updates(%HostReadModel{
id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
}) do
@spec discover_host_software_updates(String.t(), String.t()) ::
{:ok, any()} | {:error, any()}
def discover_host_software_updates(_, nil), do: {:error, :host_without_fqdn}

@spec discover_host_software_updates(String.t(), String.t()) ::
{:ok, any()} | {:error, any()}
def discover_host_software_updates(host_id, fully_qualified_domain_name) do
with {:ok, system_id} <- get_system_id(fully_qualified_domain_name),
{:ok, relevant_patches} <- get_relevant_patches(system_id),
:ok <-
Expand Down
7 changes: 7 additions & 0 deletions test/support/factory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ defmodule Trento.Factory do
HostDetailsUpdated,
HostHealthChanged,
HostRegistered,
HostRestored,
HostSaptuneHealthChanged,
HostTombstoned,
SaptuneStatusUpdated,
Expand Down Expand Up @@ -139,6 +140,12 @@ defmodule Trento.Factory do
}
end

def host_restored_event_factory do
%HostRestored{
host_id: Faker.UUID.v4()
}
end

def host_factory do
%HostReadModel{
id: Faker.UUID.v4(),
Expand Down
38 changes: 1 addition & 37 deletions test/trento/hosts/host_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ defmodule Trento.Hosts.HostTest do
CompleteHostChecksExecution,
CompleteSoftwareUpdatesDiscovery,
DeregisterHost,
DiscoverSoftwareUpdates,
RegisterHost,
RequestHostDeregistration,
RollUpHost,
Expand Down Expand Up @@ -38,8 +37,7 @@ defmodule Trento.Hosts.HostTest do
SaptuneStatusUpdated,
SlesSubscriptionsUpdated,
SoftwareUpdatesDiscoveryCleared,
SoftwareUpdatesDiscoveryCompleted,
SoftwareUpdatesDiscoveryRequested
SoftwareUpdatesDiscoveryCompleted
}

alias Trento.Hosts.ValueObjects.{
Expand Down Expand Up @@ -1410,7 +1408,6 @@ defmodule Trento.Hosts.HostTest do
describe "software updates discovery" do
test "should not accept software updates discovery commands if a host is not registered yet" do
commands = [
%DiscoverSoftwareUpdates{host_id: Faker.UUID.v4()},
%CompleteSoftwareUpdatesDiscovery{host_id: Faker.UUID.v4()},
%ClearSoftwareUpdatesDiscovery{host_id: Faker.UUID.v4()}
]
Expand All @@ -1420,37 +1417,6 @@ defmodule Trento.Hosts.HostTest do
end
end

test "should trigger the software updates discovery process" do
host_id = Faker.UUID.v4()
fully_qualified_domain_name = Faker.Internet.domain_name()

initial_events = [
build(:host_registered_event,
host_id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
),
build(:heartbeat_succeded, host_id: host_id)
]

assert_events_and_state(
initial_events,
DiscoverSoftwareUpdates.new!(%{
host_id: host_id
}),
%SoftwareUpdatesDiscoveryRequested{
host_id: host_id,
fully_qualified_domain_name: fully_qualified_domain_name
},
fn host ->
assert %Host{
host_id: ^host_id,
fully_qualified_domain_name: ^fully_qualified_domain_name,
heartbeat: Health.passing()
} = host
end
)
end

defp get_host_health_changed_event(host_id, scenario) do
case Map.get(scenario, :expect_host_health_changed, true) do
true ->
Expand Down Expand Up @@ -1762,7 +1728,6 @@ defmodule Trento.Hosts.HostTest do
vpc_id: "vpc-12345"
}
}),
DiscoverSoftwareUpdates.new!(%{host_id: host_id}),
RollUpHost.new!(%{
host_id: host_id
})
Expand Down Expand Up @@ -1946,7 +1911,6 @@ defmodule Trento.Hosts.HostTest do
%UpdateHeartbeat{host_id: host_id},
%UpdateProvider{host_id: host_id},
%UpdateSlesSubscriptions{host_id: host_id},
%DiscoverSoftwareUpdates{host_id: host_id},
%CompleteSoftwareUpdatesDiscovery{host_id: host_id},
%ClearSoftwareUpdatesDiscovery{host_id: host_id},
%SelectHostChecks{host_id: host_id}
Expand Down
Loading