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

Suse manager settings refactor #2788

Merged
merged 7 commits into from
Jul 16, 2024
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
16 changes: 0 additions & 16 deletions assets/js/lib/api/softwareUpdatesSettings.js

This file was deleted.

15 changes: 15 additions & 0 deletions assets/js/lib/api/suseManagerSettings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { networkClient } from '@lib/network';

export const getSettings = () => networkClient.get(`/settings/suse_manager`);

export const saveSettings = (settings) =>
networkClient.post(`/settings/suse_manager`, settings);

export const updateSettings = (settings) =>
networkClient.patch(`/settings/suse_manager`, settings);

export const clearSettings = () =>
networkClient.delete(`/settings/suse_manager`);

export const testConnection = () =>
networkClient.post(`/settings/suse_manager/test`);
2 changes: 1 addition & 1 deletion assets/js/state/sagas/hosts.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ describe('Hosts sagas', () => {

const settingsResponse = softwareUpdatesSettingsFactory.build();

axiosMock.onGet('/settings/suma_credentials').reply(200, settingsResponse);
axiosMock.onGet('/settings/suse_manager').reply(200, settingsResponse);

const softwareUpdatesResponse = {
relevant_patches: [
Expand Down
2 changes: 1 addition & 1 deletion assets/js/state/sagas/softwareUpdatesSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
updateSettings,
clearSettings,
testConnection,
} from '@lib/api/softwareUpdatesSettings';
} from '@lib/api/suseManagerSettings';

import {
FETCH_SOFTWARE_UPDATES_SETTINGS,
Expand Down
26 changes: 11 additions & 15 deletions assets/js/state/sagas/softwareUpdatesSettings.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ describe('Software Updates Settings saga', () => {
const axiosMock = new MockAdapter(networkClient);
const successfulResponse = softwareUpdatesSettingsFactory.build();

axiosMock
.onGet('/settings/suma_credentials')
.reply(200, successfulResponse);
axiosMock.onGet('/settings/suse_manager').reply(200, successfulResponse);

const dispatched = await recordSaga(fetchSoftwareUpdatesSettings);

Expand All @@ -46,7 +44,7 @@ describe('Software Updates Settings saga', () => {
it('should empty software updates settings when no configured settings were found', async () => {
const axiosMock = new MockAdapter(networkClient);

axiosMock.onGet('/settings/suma_credentials').reply(404);
axiosMock.onGet('/settings/suse_manager').reply(404);

const dispatched = await recordSaga(fetchSoftwareUpdatesSettings);

Expand All @@ -60,7 +58,7 @@ describe('Software Updates Settings saga', () => {
'should empty software updates settings and put a network error flag on failed fetching',
async (status) => {
const axiosMock = new MockAdapter(networkClient);
axiosMock.onGet('/settings/suma_credentials').reply(status);
axiosMock.onGet('/settings/suse_manager').reply(status);

const dispatched = await recordSaga(fetchSoftwareUpdatesSettings);

Expand Down Expand Up @@ -89,9 +87,7 @@ describe('Software Updates Settings saga', () => {
ca_uploaded_at: caUploadedAt,
});

axiosMock
.onPost('/settings/suma_credentials')
.reply(201, successfulResponse);
axiosMock.onPost('/settings/suse_manager').reply(201, successfulResponse);

const dispatched = await recordSaga(saveSoftwareUpdatesSettings, {
payload,
Expand Down Expand Up @@ -126,7 +122,7 @@ describe('Software Updates Settings saga', () => {
},
];

axiosMock.onPost('/settings/suma_credentials', payload).reply(422, {
axiosMock.onPost('/settings/suse_manager', payload).reply(422, {
errors,
});

Expand Down Expand Up @@ -158,7 +154,7 @@ describe('Software Updates Settings saga', () => {
});

axiosMock
.onPatch('/settings/suma_credentials')
.onPatch('/settings/suse_manager')
.reply(200, successfulResponse);

const dispatched = await recordSaga(
Expand Down Expand Up @@ -200,7 +196,7 @@ describe('Software Updates Settings saga', () => {
},
];

axiosMock.onPatch('/settings/suma_credentials', payload).reply(422, {
axiosMock.onPatch('/settings/suse_manager', payload).reply(422, {
errors,
});

Expand All @@ -219,7 +215,7 @@ describe('Software Updates Settings saga', () => {
it('should successfully clear software updates settings', async () => {
const axiosMock = new MockAdapter(networkClient);

axiosMock.onDelete('/settings/suma_credentials').reply(204);
axiosMock.onDelete('/settings/suse_manager').reply(204);

const dispatched = await recordSaga(clearSoftwareUpdatesSettings);

Expand All @@ -236,7 +232,7 @@ describe('Software Updates Settings saga', () => {
{ detail: 'Something went wrong.', title: 'Internal Server Error' },
];

axiosMock.onDelete('/settings/suma_credentials').reply(500, {
axiosMock.onDelete('/settings/suse_manager').reply(500, {
errors,
});

Expand All @@ -253,7 +249,7 @@ describe('Software Updates Settings saga', () => {
it('should notify on successful connection test', async () => {
const axiosMock = new MockAdapter(networkClient);

axiosMock.onPost('/settings/suma_credentials/test').reply(200);
axiosMock.onPost('/settings/suse_manager/test').reply(200);

const dispatched = await recordSaga(testSoftwareUpdatesConnection);

Expand All @@ -269,7 +265,7 @@ describe('Software Updates Settings saga', () => {
async (errorStatus) => {
const axiosMock = new MockAdapter(networkClient);

axiosMock.onPost('/settings/suma_credentials/test').reply(errorStatus);
axiosMock.onPost('/settings/suse_manager/test').reply(errorStatus);

const dispatched = await recordSaga(testSoftwareUpdatesConnection);

Expand Down
6 changes: 3 additions & 3 deletions lib/trento/activity_logging/activity_catalog.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ defmodule Trento.ActivityLog.ActivityCatalog do

@login_attempt {TrentoWeb.SessionController, :create}
@api_key_generation {TrentoWeb.V1.SettingsController, :update_api_key_settings}
@saving_suma_settings {TrentoWeb.V1.SUMACredentialsController, :create}
@changing_suma_settings {TrentoWeb.V1.SUMACredentialsController, :update}
@clearing_suma_settings {TrentoWeb.V1.SUMACredentialsController, :delete}
@saving_suma_settings {TrentoWeb.V1.SettingsController, :save_suse_manager_settings}
@changing_suma_settings {TrentoWeb.V1.SettingsController, :update_suse_manager_settings}
@clearing_suma_settings {TrentoWeb.V1.SettingsController, :delete_suse_manager_settings}
@tagging {TrentoWeb.V1.TagsController, :add_tag}
@untagging {TrentoWeb.V1.TagsController, :remove_tag}
@user_creation {TrentoWeb.V1.UsersController, :create}
Expand Down
4 changes: 2 additions & 2 deletions lib/trento/infrastructure/software_updates/auth/suma_auth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule Trento.Infrastructure.SoftwareUpdates.Auth.SumaAuth do

alias Trento.Infrastructure.SoftwareUpdates.Auth.State
alias Trento.Infrastructure.SoftwareUpdates.SumaApi
alias Trento.SoftwareUpdates
alias Trento.Settings

@default_name "suma_authentication"

Expand Down Expand Up @@ -77,7 +77,7 @@ defmodule Trento.Infrastructure.SoftwareUpdates.Auth.SumaAuth do

defp setup_auth(%State{auth: nil} = state) do
with {:ok, %{url: url, username: username, password: password, ca_cert: ca_cert}} <-
SoftwareUpdates.get_settings(),
Settings.get_suse_manager_settings(),
{:ok, auth_cookie} <- SumaApi.login(url, username, password, ca_cert) do
{:ok,
%State{
Expand Down
114 changes: 113 additions & 1 deletion lib/trento/settings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,32 @@ defmodule Trento.Settings do
alias Trento.Repo

alias Trento.Hosts.Projections.SlesSubscriptionReadModel
alias Trento.SoftwareUpdates.Discovery, as: SoftwareUpdatesDiscovery

alias Trento.Settings.{
ApiKeySettings,
InstallationSettings
InstallationSettings,
SuseManagerSettings
}

alias Trento.Support.DateService

require Logger

@type suse_manager_settings_save_submission :: %{
url: String.t(),
username: String.t(),
password: String.t(),
ca_cert: String.t() | nil
}

@type suse_manager_settings_change_submission :: %{
url: String.t() | nil,
username: String.t() | nil,
password: String.t() | nil,
ca_cert: String.t() | nil
}

@sles_identifier "SLES_SAP"

@spec get_installation_id :: String.t()
Expand Down Expand Up @@ -78,4 +96,98 @@ defmodule Trento.Settings do
error
end
end

# SUMA settings

@spec get_suse_manager_settings ::
{:ok, SuseManagerSettings.t()} | {:error, :settings_not_configured}
def get_suse_manager_settings do
settings = Repo.one(SuseManagerSettings.base_query())

if settings do
{:ok, settings}
else
{:error, :settings_not_configured}
end
end

@spec save_suse_manager_settings(suse_manager_settings_save_submission, module()) ::
{:ok, SuseManagerSettings.t()}
| {:error, :settings_already_configured}
| {:error, any()}
def save_suse_manager_settings(settings_submission, date_service \\ DateService) do
with {:ok, :settings_not_configured, settings} <- ensure_no_suse_manager_settings_configured() do
settings
|> save_or_update_suse_manager_settings(settings_submission, date_service)
|> log_error("Error while saving software updates settings")
end
end

@spec change_suse_manager_settings(suse_manager_settings_change_submission, module()) ::
{:ok, SuseManagerSettings.t()}
| {:error, :settings_not_configured}
| {:error, any()}
def change_suse_manager_settings(settings_submission, date_service \\ DateService) do
with {:ok, settings} <- get_suse_manager_settings() do
settings
|> save_or_update_suse_manager_settings(settings_submission, date_service)
|> log_error("Error while updating software updates settings")
end
end

@spec clear_suse_manager_settings :: :ok
def clear_suse_manager_settings do
Repo.delete_all(SuseManagerSettings.base_query())

SoftwareUpdatesDiscovery.clear_software_updates_discoveries()

:ok
end

defp ensure_no_suse_manager_settings_configured do
case Repo.one(SuseManagerSettings.base_query()) do
nil ->
{:ok, :settings_not_configured, nil}

%SuseManagerSettings{} ->
Logger.error("Error: software updates settings already configured")
{:error, :settings_already_configured}
end
end

defp save_or_update_suse_manager_settings(settings, settings_submission, date_service) do
result =
case settings do
nil ->
%SuseManagerSettings{}
|> SuseManagerSettings.changeset(settings_submission, date_service)
|> Repo.insert()

%SuseManagerSettings{} ->
settings
|> SuseManagerSettings.changeset(settings_submission, date_service)
|> Repo.update()
end

case result do
{:ok, _} = success ->
SoftwareUpdatesDiscovery.clear()

Task.Supervisor.start_child(Trento.TasksSupervisor, fn ->
SoftwareUpdatesDiscovery.discover_software_updates()
end)

success

{:error, _} = error ->
error
end
end

defp log_error({:error, _} = error, message) do
Logger.error("#{message}: #{inspect(error)}")
error
end

defp log_error(result, _), do: result
end
13 changes: 13 additions & 0 deletions lib/trento/settings/policy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Trento.Settings.Policy do
import Trento.Support.PolicyHelper
alias Trento.ActivityLog.Settings, as: ActivityLogSettings
alias Trento.Settings.ApiKeySettings
alias Trento.Settings.SuseManagerSettings

alias Trento.Users.User

Expand All @@ -20,11 +21,23 @@ defmodule Trento.Settings.Policy do
def authorize(:update_activity_log_settings, %User{} = user, ActivityLogSettings),
do: has_global_ability?(user) or has_activity_logs_settings_change_ability?(user)

def authorize(action, %User{} = user, SuseManagerSettings)
when action in [
:save_suse_manager_settings,
:update_suse_manager_settings,
:delete_suse_manager_settings
] do
has_global_ability?(user) or has_suma_settings_change_ability?(user)
end

def authorize(_, _, _), do: true

defp has_api_key_settings_change_ability?(user),
do: user_has_ability?(user, %{name: "all", resource: "api_key_settings"})

defp has_activity_logs_settings_change_ability?(user),
do: user_has_ability?(user, %{name: "all", resource: "activity_logs_settings"})

defp has_suma_settings_change_ability?(user),
do: user_has_ability?(user, %{name: "all", resource: "suma_settings"})
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule Trento.SoftwareUpdates.Settings do
defmodule Trento.Settings.SuseManagerSettings do
@moduledoc """
Schema for software updates settings.
Schema for suse manager settings.
"""

use Ecto.Schema
Expand Down
Loading