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

Identify clustered sap instances #3397

Merged
merged 8 commits into from
Mar 25, 2025
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
23 changes: 21 additions & 2 deletions lib/trento/clusters.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ defmodule Trento.Clusters do

alias Trento.Clusters.Commands.SelectChecks

alias Trento.Clusters.ValueObjects.SapInstance

alias Trento.SapSystems.Projections.SapSystemReadModel

alias Trento.Infrastructure.Checks
Expand Down Expand Up @@ -159,6 +161,21 @@ defmodule Trento.Clusters do

def resource_managed?(_, _), do: false

@spec get_sap_instances_by_host_id(String.t()) :: [SapInstance.t()]
def get_sap_instances_by_host_id(host_id) do
query =
from c in ClusterReadModel,
join: h in HostReadModel,
on: h.cluster_id == c.id,
where: h.id == ^host_id,
select: c.sap_instances

case Repo.one(query) do
nil -> []
sap_instances -> sap_instances
end
Comment on lines +173 to +176
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will raise an exception if there's more than one result, IIRC.

Copy link
Contributor Author

@arbulu89 arbulu89 Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the host_id, UUID and primary key in the database. It is impossible by database definition as the host can only have one cluster.
But thank you for pointing it out, you never know until you double-check hehe

end

defp has_resource_managed?(%{nodes: nodes}, resource_id) do
Enum.any?(nodes, fn %{resources: resources} ->
Enum.find_value(resources, false, fn %{parent: parent} = resource ->
Expand Down Expand Up @@ -188,18 +205,20 @@ defmodule Trento.Clusters do
id: cluster_id,
provider: provider,
type: ClusterType.ascs_ers(),
additional_sids: cluster_sids,
sap_instances: sap_instances,
selected_checks: selected_checks
} = cluster
) do
sap_instance_sids = SapInstance.get_sap_instance_sids(sap_instances)

hosts_data =
Repo.all(
from h in HostReadModel,
join: a in ApplicationInstanceReadModel,
on: h.id == a.host_id,
where:
h.cluster_id == ^cluster_id and is_nil(h.deregistered_at) and
a.sid in ^cluster_sids,
a.sid in ^sap_instance_sids,
select: %{host_id: h.id, sap_system_id: a.sap_system_id}
)

Expand Down
40 changes: 15 additions & 25 deletions lib/trento/clusters/cluster.ex
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ defmodule Trento.Clusters.Cluster do

alias Trento.Clusters.ValueObjects.{
AscsErsClusterDetails,
HanaClusterDetails
HanaClusterDetails,
SapInstance
}

alias Trento.Clusters.Commands.{
Expand Down Expand Up @@ -114,8 +115,6 @@ defmodule Trento.Clusters.Cluster do
field :cluster_id, Ecto.UUID
field :name, :string
field :type, Ecto.Enum, values: ClusterType.values()
field :sid, :string
field :additional_sids, {:array, :string}, default: []
field :resources_number, :integer
field :hosts_number, :integer
field :provider, Ecto.Enum, values: Provider.values()
Expand All @@ -136,6 +135,8 @@ defmodule Trento.Clusters.Cluster do
ascs_ers: [module: AscsErsClusterDetails, identify_by_fields: [:sap_systems]]
],
on_replace: :update

embeds_many :sap_instances, SapInstance
end

def execute(%Cluster{rolling_up: true}, _), do: {:error, :cluster_rolling_up}
Expand All @@ -149,8 +150,7 @@ defmodule Trento.Clusters.Cluster do
host_id: host_id,
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -164,8 +164,7 @@ defmodule Trento.Clusters.Cluster do
cluster_id: cluster_id,
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -192,8 +191,7 @@ defmodule Trento.Clusters.Cluster do
cluster_id: cluster_id,
name: name,
type: :unknown,
sid: nil,
additional_sids: [],
sap_instances: [],
provider: :unknown,
resources_number: nil,
hosts_number: nil,
Expand Down Expand Up @@ -343,8 +341,7 @@ defmodule Trento.Clusters.Cluster do
cluster_id: cluster_id,
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -357,8 +354,7 @@ defmodule Trento.Clusters.Cluster do
| cluster_id: cluster_id,
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand Down Expand Up @@ -391,8 +387,7 @@ defmodule Trento.Clusters.Cluster do
%ClusterDetailsUpdated{
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -403,8 +398,7 @@ defmodule Trento.Clusters.Cluster do
cluster
| name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand Down Expand Up @@ -503,8 +497,7 @@ defmodule Trento.Clusters.Cluster do
%Cluster{
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -513,8 +506,7 @@ defmodule Trento.Clusters.Cluster do
%RegisterClusterHost{
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -530,8 +522,7 @@ defmodule Trento.Clusters.Cluster do
cluster_id: cluster_id,
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand All @@ -542,8 +533,7 @@ defmodule Trento.Clusters.Cluster do
cluster_id: cluster_id,
name: name,
type: type,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
resources_number: resources_number,
hosts_number: hosts_number,
Expand Down
7 changes: 4 additions & 3 deletions lib/trento/clusters/commands/register_cluster_host.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ defmodule Trento.Clusters.Commands.RegisterClusterHost do

alias Trento.Clusters.ValueObjects.{
AscsErsClusterDetails,
HanaClusterDetails
HanaClusterDetails,
SapInstance
}

defcommand do
field :cluster_id, Ecto.UUID
field :host_id, Ecto.UUID
field :name, :string
field :type, Ecto.Enum, values: ClusterType.values()
field :sid, :string
field :additional_sids, {:array, :string}
field :provider, Ecto.Enum, values: Provider.values()
field :designated_controller, :boolean
field :resources_number, :integer
Expand All @@ -46,5 +45,7 @@ defmodule Trento.Clusters.Commands.RegisterClusterHost do
ascs_ers: [module: AscsErsClusterDetails, identify_by_fields: [:sap_systems]]
],
on_replace: :update

embeds_many :sap_instances, SapInstance
end
end
7 changes: 7 additions & 0 deletions lib/trento/clusters/enums/sap_instance_resource_type.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule Trento.Clusters.Enums.SapInstanceResourceType do
@moduledoc """
Type that represents the discovered type of a clustered SAP instance.
"""

use Trento.Support.Enum, values: [:sap_hana_topology, :sap_instance]
end
7 changes: 4 additions & 3 deletions lib/trento/clusters/events/cluster_details_updated.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ defmodule Trento.Clusters.Events.ClusterDetailsUpdated do

alias Trento.Clusters.ValueObjects.{
AscsErsClusterDetails,
HanaClusterDetails
HanaClusterDetails,
SapInstance
}

defevent do
field :cluster_id, Ecto.UUID
field :name, :string
field :type, Ecto.Enum, values: ClusterType.values()
field :sid, :string
field :additional_sids, {:array, :string}, default: []
field :provider, Ecto.Enum, values: Provider.values()
field :resources_number, :integer
field :hosts_number, :integer
Expand All @@ -32,5 +31,7 @@ defmodule Trento.Clusters.Events.ClusterDetailsUpdated do
ascs_ers: [module: AscsErsClusterDetails, identify_by_fields: [:sap_systems]]
],
on_replace: :update

embeds_many :sap_instances, SapInstance
end
end
7 changes: 4 additions & 3 deletions lib/trento/clusters/events/cluster_registered.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ defmodule Trento.Clusters.Events.ClusterRegistered do

alias Trento.Clusters.ValueObjects.{
AscsErsClusterDetails,
HanaClusterDetails
HanaClusterDetails,
SapInstance
}

defevent do
field :cluster_id, Ecto.UUID
field :name, :string
field :type, Ecto.Enum, values: ClusterType.values()
field :sid, :string
field :additional_sids, {:array, :string}, default: []
field :provider, Ecto.Enum, values: Provider.values()
field :resources_number, :integer
field :hosts_number, :integer
Expand All @@ -34,5 +33,7 @@ defmodule Trento.Clusters.Events.ClusterRegistered do
ascs_ers: [module: AscsErsClusterDetails, identify_by_fields: [:sap_systems]]
],
on_replace: :update

embeds_many :sap_instances, SapInstance
end
end
12 changes: 4 additions & 8 deletions lib/trento/clusters/projections/cluster_projector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ defmodule Trento.Clusters.Projections.ClusterProjector do
%ClusterRegistered{
cluster_id: id,
name: name,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
type: type,
resources_number: resources_number,
Expand All @@ -43,8 +42,7 @@ defmodule Trento.Clusters.Projections.ClusterProjector do
ClusterReadModel.changeset(%ClusterReadModel{}, %{
id: id,
name: name,
sid: sid,
additional_sids: additional_sids,
sap_instances: Enum.map(sap_instances, &Map.from_struct/1),
provider: provider,
type: type,
resources_number: resources_number,
Expand Down Expand Up @@ -94,8 +92,7 @@ defmodule Trento.Clusters.Projections.ClusterProjector do
%ClusterDetailsUpdated{
cluster_id: id,
name: name,
sid: sid,
additional_sids: additional_sids,
sap_instances: sap_instances,
provider: provider,
type: type,
resources_number: resources_number,
Expand All @@ -108,8 +105,7 @@ defmodule Trento.Clusters.Projections.ClusterProjector do
|> Repo.get!(id)
|> ClusterReadModel.changeset(%{
name: name,
sid: sid,
additional_sids: additional_sids,
sap_instances: Enum.map(sap_instances, &Map.from_struct/1),
provider: provider,
type: type,
resources_number: resources_number,
Expand Down
10 changes: 7 additions & 3 deletions lib/trento/clusters/projections/cluster_read_model.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ defmodule Trento.Clusters.Projections.ClusterReadModel do

alias Trento.Hosts.Projections.HostReadModel

alias Trento.Clusters.ValueObjects.SapInstance

alias Trento.Tags.Tag

defdelegate authorize(action, user, params), to: Trento.Clusters.Policy
Expand All @@ -26,8 +28,6 @@ defmodule Trento.Clusters.Projections.ClusterReadModel do
@primary_key {:id, :binary_id, autogenerate: false}
schema "clusters" do
field :name, :string, default: ""
field :sid, :string
field :additional_sids, {:array, :string}, default: []
field :provider, Ecto.Enum, values: Provider.values()
field :type, Ecto.Enum, values: ClusterType.values()
field :selected_checks, {:array, :string}, default: []
Expand All @@ -43,6 +43,8 @@ defmodule Trento.Clusters.Projections.ClusterReadModel do
foreign_key: :cluster_id,
where: [deregistered_at: nil]

embeds_many :sap_instances, SapInstance, on_replace: :delete

# Virtually enriched fields
field :cib_last_written, :string, virtual: true

Expand All @@ -53,6 +55,8 @@ defmodule Trento.Clusters.Projections.ClusterReadModel do

@spec changeset(t() | Ecto.Changeset.t(), map) :: Ecto.Changeset.t()
def changeset(cluster, attrs) do
cast(cluster, attrs, __MODULE__.__schema__(:fields))
cluster
|> cast(attrs, __MODULE__.__schema__(:fields) -- [:sap_instances])
|> cast_embed(:sap_instances)
end
end
39 changes: 39 additions & 0 deletions lib/trento/clusters/value_objects/sap_instance.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule Trento.Clusters.ValueObjects.SapInstance do
@moduledoc """
Clustered SAP instance
"""
@required_fields [:name, :sid, :instance_number, :resource_type]

use Trento.Support.Type

require Trento.Clusters.Enums.SapInstanceResourceType, as: SapInstanceResourceType

deftype do
field :name, :string
field :sid, :string
field :instance_number, :string
field :hostname, :string
field :resource_type, Ecto.Enum, values: SapInstanceResourceType.values()
end

@spec get_hana_instance_sid([__MODULE__.t()]) :: String.t()
def get_hana_instance_sid(sap_instances) do
Enum.find_value(sap_instances, "", fn %{resource_type: resource_type, sid: sid} ->
if resource_type == SapInstanceResourceType.sap_hana_topology() do
sid
else
nil
end
end)
end

@spec get_sap_instance_sids([__MODULE__.t()]) :: [String.t()]
def get_sap_instance_sids(sap_instances) do
sap_instances
|> Enum.filter(fn %{resource_type: resource_type} ->
resource_type == SapInstanceResourceType.sap_instance()
end)
|> Enum.map(fn %{sid: sid} -> sid end)
|> Enum.uniq()
end
end
Loading
Loading