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

Add initiation for software updates discovery process #2498

Merged
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
13 changes: 13 additions & 0 deletions lib/trento/hosts/commands/discover_software_updates.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule Trento.Hosts.Commands.DiscoverSoftwareUpdates do
@moduledoc """
Issues the software updates discovery for a host
"""

@required_fields :all

use Trento.Support.Command

defcommand do
field :host_id, Ecto.UUID
end
end
12 changes: 12 additions & 0 deletions lib/trento/hosts/events/software_updates_discovery_requested.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule Trento.Hosts.Events.SoftwareUpdatesDiscoveryRequested do
@moduledoc """
This event is emitted when a host's software updates discovery process is issued
"""

use Trento.Support.Event

defevent do
field :host_id, Ecto.UUID
field :fully_qualified_domain_name, :string
end
end
35 changes: 30 additions & 5 deletions lib/trento/hosts/host.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ defmodule Trento.Hosts.Host do
Every time a checks execution for a host completes the execution's result is taken into account to determine host's health.
Checks execution is started either by an explicit user request or periodically as per the scheduler configuration.

### Software Updates Discovery health
### Software Updates Discovery

The Software Updates Discovery health is obtained from the integration with an external service, SUMA,
that provides information about relevant patches and upgradable packages for the host.
Presence of relevant patches concurs to the host's aggregated health as follows:
Business process integrating with an external service, SUMA, determining relevant patches and upgradable packages for a host.
Process is triggered
- on host registration
- when the fqdn of the host changes
- on host restoration
- every given amount of time
- on demand (ie the integration settings with the external service change)

Presence of relevant patches determines Software Updates Discovery health and concurs to the host's aggregated health as follows:
- critical if there is at least one security advisory
- warning if there are only buxfixes/software enhancements
"""
Expand Down Expand Up @@ -70,6 +76,7 @@ defmodule Trento.Hosts.Host do
CompleteHostChecksExecution,
CompleteSoftwareUpdatesDiscovery,
DeregisterHost,
DiscoverSoftwareUpdates,
RegisterHost,
RequestHostDeregistration,
RollUpHost,
Expand Down Expand Up @@ -99,7 +106,8 @@ defmodule Trento.Hosts.Host do
SaptuneStatusUpdated,
SlesSubscriptionsUpdated,
SoftwareUpdatesDiscoveryCleared,
SoftwareUpdatesDiscoveryCompleted
SoftwareUpdatesDiscoveryCompleted,
SoftwareUpdatesDiscoveryRequested
}

@required_fields []
Expand Down Expand Up @@ -528,6 +536,21 @@ defmodule Trento.Hosts.Host do
|> Multi.execute(&maybe_emit_host_health_changed_event/1)
end

# 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 @@ -714,6 +737,8 @@ defmodule Trento.Hosts.Host do
}
end

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

def apply(
%Host{} = host,
%SoftwareUpdatesDiscoveryCompleted{
Expand Down
2 changes: 2 additions & 0 deletions lib/trento/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule Trento.Router do
CompleteHostChecksExecution,
CompleteSoftwareUpdatesDiscovery,
DeregisterHost,
DiscoverSoftwareUpdates,
RegisterHost,
RequestHostDeregistration,
RollUpHost,
Expand Down Expand Up @@ -55,6 +56,7 @@ defmodule Trento.Router do
RequestHostDeregistration,
DeregisterHost,
CompleteHostChecksExecution,
DiscoverSoftwareUpdates,
CompleteSoftwareUpdatesDiscovery,
ClearSoftwareUpdatesDiscovery
],
Expand Down
55 changes: 44 additions & 11 deletions test/trento/hosts/host_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Trento.Hosts.HostTest do
CompleteHostChecksExecution,
CompleteSoftwareUpdatesDiscovery,
DeregisterHost,
DiscoverSoftwareUpdates,
RegisterHost,
RequestHostDeregistration,
RollUpHost,
Expand Down Expand Up @@ -37,7 +38,8 @@ defmodule Trento.Hosts.HostTest do
SaptuneStatusUpdated,
SlesSubscriptionsUpdated,
SoftwareUpdatesDiscoveryCleared,
SoftwareUpdatesDiscoveryCompleted
SoftwareUpdatesDiscoveryCompleted,
SoftwareUpdatesDiscoveryRequested
}

alias Trento.Hosts.ValueObjects.{
Expand Down Expand Up @@ -1408,6 +1410,7 @@ 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 @@ -1417,6 +1420,37 @@ 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 @@ -1713,8 +1747,7 @@ defmodule Trento.Hosts.HostTest do
}
]

assert_error(
events,
commands_to_reject = [
UpdateProvider.new!(%{
host_id: host_id,
provider: :azure,
Expand All @@ -1729,16 +1762,15 @@ defmodule Trento.Hosts.HostTest do
vpc_id: "vpc-12345"
}
}),
{:error, :host_rolling_up}
)

assert_error(
events,
DiscoverSoftwareUpdates.new!(%{host_id: host_id}),
RollUpHost.new!(%{
host_id: host_id
}),
{:error, :host_rolling_up}
)
})
]

for command <- commands_to_reject do
assert_error(events, command, {:error, :host_rolling_up})
end
end

test "should apply the rollup event and rehydrate the aggregate" do
Expand Down Expand Up @@ -1914,6 +1946,7 @@ 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