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

Simplified Proxy Onboarding #9703

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

rjpmestre
Copy link
Contributor

@rjpmestre rjpmestre commented Jan 29, 2025

Warning

This PR is a work in progress. While the core functionality is in place, there are still multiple scenarios to address and details to refine. This PR is intended to gather early feedback on the current implementation, considering the known issues (listed at the end).

What does this PR change?

This PR implements a new feature that aims to simplify the proxy onboarding process (following discussions at https://github.com/SUSE/spacewalk/issues/24680 and https://github.com/SUSE/spacewalk/issues/23714).
Currently, setting up a proxy involves the following steps: onboarding the minion, creating a proxy configuration file, installing Podman and mgrpxy (provided by uyuni tools), and finally running mgrpxy install.

For this initial feature iteration, our goal is to streamline the process by extending the existing web UI functionality (Container Based Proxy Configuration). Once the user fills in the necessary information in a form, the system will automatically set up the minion as a proxy with minimal manual intervention.

GUI diff

  • System overview page will display a Convert to Proxy button if it fits minion's pre-requisites (check below)
  • Entering the "Proxy" tab on minion details (under 2nd level tab) will now display a 3rd level menu for "Configuration", "Connection" and "Clients";
  • Details / Proxy / Configuration page will display a new form (more details below) addressing the configurations that should be applied to the proxy;
  • Details / Proxy / Connection -> Moved from Details / Connection;
  • Details / Proxy / Clients -> Moved from Details / Proxy.
  • DONE

Documentation

TBD

  • DONE

Test coverage

TBD

  • DONE

Changelogs

Make sure the changelogs entries you are adding are compliant with https://github.com/uyuni-project/uyuni/wiki/Contributing#changelogs and https://github.com/uyuni-project/uyuni/wiki/Contributing#uyuni-projectuyuni-repository

If you don't need a changelog check, please mark this checkbox:

  • No changelog needed

If you uncheck the checkbox after the PR is created, you will need to re-run changelog_test (see below)

Re-run a test

If you need to re-run a test, please mark the related checkbox, it will be unchecked automatically once it has re-run:

  • Re-run test "changelog_test"
  • Re-run test "backend_unittests_pgsql"
  • Re-run test "java_pgsql_tests"
  • Re-run test "schema_migration_test_pgsql"
  • Re-run test "susemanager_unittests"
  • Re-run test "javascript_lint"
  • Re-run test "spacecmd_unittests"

Before you merge

Check How to branch and merge properly!

Documentation Support

Pre-requisites

  • minion is onboarded
  • minion is reachable
  • minion has access to Uyuni Client Tools (via Software Channels/spacewalk-common-channels)
  • minion can be convertible to a proxy* or has a proxy entitlement

Note

Whether a minion can be converted to a proxy depends on the running manager:

  • SUSE Manager (SUMA) only allows transactional servers (for supportability reasons).
  • Uyuni allows all minions.
  • In both cases, the minion must not already be a proxy.

Base Setup

If an onboarded minion meets the prerequisites to become a proxy, the first step is to go to the minion's Overview page. From there:

  1. Navigate to Details > Properties.
  2. Add "Proxy" under Add-On System Types.
  3. Click Update Properties.
    This action will make a new main tab, Proxy, visible.
    Alternatively, the user can achieve the same result by clicking Convert to Proxy in the top-right corner of the Overview page.
    The Proxy tab is intended to display data and provide operations related to the proxy. At this stage, it will only contain the form used to apply the proxy configurations to the minion.

WebUI Form

Name Type Values/Restrictions Notes
Parent FQDN Select Running manager instance and all proxies
Proxy SSH port Input (int) Range 1 - 65535, default 8022
Max Squid cache size Input (int) Default 100 In GB
Proxy admin email Input (string)
Certificates Radio box "Keep", "Replace" "Replace" is the default value. Only visible if an existing configuration exists.
Root CA File input Visible only if "Keep" is selected
Proxy certificate File input Visible only if "Keep" is selected
Proxy SSL private key File input Visible only if "Keep" is selected
Intermediate CAs Multiple file input Visible only if "Keep" is selected
Source Radio box "Registry", "RPM"
Registry Radio box "Simple", "Advanced" Visible only if "Registry" is selected
Registry URL Input (string) Visible and required only if "Simple" is selected
Registry Tag Select Visible and required only if "Simple" is selected. Options filled once "Registry URL" is validated.
HTTPD URL Input (string) Visible and required only if "Advanced" is selected
HTTPD Tag Select Visible and required only if "Advanced" is selected. Options filled once "HTTPD URL" is validated.
Salt Broker URL Input (string) Visible and required only if "Advanced" is selected
Salt Broker Tag Select Visible and required only if "Advanced" is selected. Options filled once "Salt Broker URL" is validated.
Squid URL Input (string) Visible and required only if "Advanced" is selected
Squid Tag Select Visible and required only if "Advanced" is selected. Options filled once "Squid URL" is validated.
SSH URL Input (string) Visible and required only if "Advanced" is selected
SSH Tag Select Visible and required only if "Advanced" is selected. Options filled once "SSH URL" is validated.
TFTPD URL Input (string) Visible and required only if "Advanced" is selected
TFTPD Tag Select Visible and required only if "Advanced" is selected. Options filled once "TFTPD URL" is validated.

Note: All visible inputs are mandatory, except the Intermediate CAs.

Flow

Once the user fills in the form and it is valid, the "Apply" button will be enabled. Clicking it will trigger the following flow:

  • Validate Inputs: Ensure that all required inputs, including registry URLs, are provided and valid.
  • Create Proxy Configuration Files (based on the Container-Based Proxy Configuration feature):
    • config.yaml
    • httpd.yaml
    • ssh.yaml
  • Save Configuration to Pillars (with category = "proxy")
  • Apply Salt State to:
    • determine the mgrpxy operation to execute (install or upgrade) and if it is a transactional server - eases following steps
    • confirm podman is installed and running;
    • confirm mgrpxy is installed;
    • copy configuration files to "/etc/uyuni/proxy";
    • if minion's local operating system is not transactional
      • execute mgrpxy install/ugrade command with custom registries if provided and log it into "/var/log/mgrpxy_install.log"
    • otherwise,
      • create a systemd "apply_mgrpxy.service" defined in "/etc/systemd/system/apply_mgrpxy.service" service file that should
        • execute mgrpxy install/ugrade command with custom registries if provided and log it into "/var/log/mgrpxy_install.log"
        • remove itself if the install/ugrade command was successful
      • enable "apply_mgrpxy.service"

Known issues

  • Convert to Proxy button is not setting proxy entitlement;
  • Applying a proxy configuration successfully isn't creating a proxy info (Convert to Proxy button is always visible);
  • Previously saved registies/tags are not restored if toggling between Source or Registry Source options;
  • When form is loaded and source is RPM, the Apply button is not enabled;
  • Bearer token is not reused for same registry realms;
  • Not meaningful fail messages back to the UI;
  • Using RPM is not installing meaningful packages. Will use defaults instead;
  • For new configurations exist (ie no proxy pillars saved) should sugest (pre-filled) repository url and tag. This behaviour is missing.
  • Any updates on the form trigger validation over registry url fields (ie, repeated tag retrieval or catalog requests);
  • Several new classes for covered by unit tests;
  • Documentation;
  • Applying salt state not registered on minion events

Copy link
Contributor

github-actions bot commented Jan 29, 2025

👋 Hello! Thanks for contributing to our project.
Acceptance tests will take some time (aprox. 1h), please be patient ☕

You can see the progress at the end of this page and at https://github.com/uyuni-project/uyuni/pull/9703/checks
Once tests finish, if they fail, you can check 👀 the cucumber report. See the link at the output of the action.
You can also check the artifacts section, which contains the logs at https://github.com/uyuni-project/uyuni/pull/9703/checks.

If you are unsure the failing tests are related to your code, you can check the "reference jobs". These are jobs that run on a scheduled time with code from master. If they fail for the same reason as your build, it means the tests or the infrastructure are broken. If they do not fail, but yours do, it means it is related to your code.

Reference tests:

KNOWN ISSUES

Sometimes the build can fail when pulling new jar files from download.opensuse.org . This is a known limitation. Given this happens rarely, when it does, all you need to do is rerun the test. Sorry for the inconvenience.

For more tips on troubleshooting, see the troubleshooting guide.

Happy hacking!
⚠️ You should not merge if acceptance tests fail to pass. ⚠️

Copy link
Contributor

github-actions bot commented Jan 29, 2025

Suggested tests to cover this Pull Request
  • proxy_container
  • srv_notifications
  • min_deblike_ssh
  • min_salt_lock_packages
  • srv_mainpage
  • srv_delete_channel_with_tool
  • srv_organization_credentials
  • allcli_system_group
  • min_action_chain
  • srv_clone_channel_npn
  • srv_user_preferences
  • srv_power_management
  • srv_dist_channel_mapping
  • srv_scc_user_credentials
  • srv_user_api
  • srv_create_dev_channels
  • srv_monitoring
  • minssh_tunnel
  • min_salt_user_states
  • srv_handle_config_channels_with_ISS_v2
  • srv_disable_scheduled_reposync
  • min_config_state_channel
  • srv_manage_channels_page
  • sle_minion
  • buildhost_bootstrap
  • srv_enable_sync_products
  • proxy_traditional_retail_mass_import
  • min_rhlike_monitoring
  • allcli_action_chain
  • srv_check_channels_page
  • srv_custom_system_info
  • min_salt_pkgset_beacon
  • srv_cobbler_sync
  • buildhost_docker_build_image
  • buildhost_osimage_build_image
  • min_rhlike_ssh
  • min_deblike_remote_command
  • proxy_container_retail_mass_import
  • min_bootstrap_reactivation
  • srv_sync_channels
  • min_deblike_openscap_audit
  • min_move_from_and_to_proxy
  • srv_cobbler_profile
  • srv_change_task_schedule
  • min_empty_system_profiles
  • min_deblike_salt
  • srv_task_status_engine
  • srv_manage_activationkey
  • srv_change_password
  • srv_payg_ssh_connection
  • min_salt_openscap_audit
  • srv_handle_software_channels_with_ISS_v2
  • min_deblike_salt_install_with_staging
  • srv_logfile
  • min_salt_install_package
  • minssh_action_chain
  • proxy_container_retail_pxeboot
  • srv_osimage
  • buildhost_docker_auth_registry
  • min_timezone
  • min_config_state_channel_api
  • min_ansible_control_node
  • min_config_state_channel_subscriptions
  • min_rhlike_remote_command
  • allcli_overview_systems_details
  • min_deblike_monitoring
  • srv_check_sync_source_packages
  • min_rhlike_salt_install_package_and_patch
  • allcli_sanity
  • min_virthost
  • srv_menu
  • srv_docker_advanced_content_management
  • min_check_patches_install
  • proxy_container_cobbler_pxeboot
  • min_salt_minions_page
  • min_bootstrap_api
  • srv_sync_fake_channels
  • min_retracted_patches
  • minssh_move_from_and_to_proxy
  • proxy_traditional_cobbler_pxeboot
  • min_recurring_action
  • srv_content_lifecycle
  • srv_salt_git_pillar
  • srv_power_management_api
  • min_bootstrap_ssh_key
  • min_salt_software_states
  • min_salt_minion_details
  • min_change_software_channel
  • srv_restart
  • min_deblike_salt_install_package
  • srv_users
  • srv_cobbler_distro
  • srv_power_management_redfish
  • srv_create_activationkey
  • srv_group_union_intersection
  • srv_cobbler_buildiso
  • srv_docker
  • srv_sync_dev_channels
  • srv_patches_page
  • min_docker_api
  • srv_reportdb
  • min_rhlike_salt
  • srv_datepicker
  • min_custom_pkg_download_endpoint
  • allcli_software_channels_dependencies
  • allcli_software_channels
  • allcli_config_channel
  • sle_ssh_minion
  • min_cve_id_new_syntax
  • min_rhlike_openscap_audit
  • srv_create_fake_repositories
  • min_monitoring
  • min_activationkey
  • min_bootstrap_negative
  • srv_salt
  • minssh_ansible_control_node
  • srv_create_fake_channels
  • min_salt_formulas
  • srv_salt_download_endpoint
  • proxy_traditional
  • allcli_reboot
  • srv_maintenance_windows
  • srv_first_settings
  • allcli_update_activationkeys
  • srv_channel_api
  • srv_docker_cve_audit
  • srv_push_package
  • min_bootstrap_script
  • srv_security
  • min_salt_formulas_advanced
  • minssh_salt_install_package
  • srv_sync_products
  • proxy_traditional_retail_pxeboot
  • srv_user_configuration_salt_states
  • minssh_bootstrap_api
  • srv_virtual_host_manager
  • srv_delete_channel_from_ui
  • min_salt_install_with_staging
  • min_cve_audit
  • proxy_container_branch_network
  • min_salt_mgrcompat_state
  • min_project_lotus
  • srv_errata_api
  • srv_activationkey_api
  • minkvm_guests
  • proxy_traditional_branch_network
  • srv_menu_filter

@rjpmestre rjpmestre force-pushed the mu-simplified_proxy_onboarding branch 6 times, most recently from 3ee4f96 to ebc14ed Compare January 31, 2025 15:17
@srbarrios
Copy link
Member

srbarrios commented Feb 10, 2025

Be aware that you need to rebase master into your PR, as we had some changes in the GH workflows.

@rjpmestre rjpmestre self-assigned this Feb 11, 2025
@rjpmestre rjpmestre force-pushed the mu-simplified_proxy_onboarding branch from ebc14ed to 4e3d051 Compare February 11, 2025 12:52
@rjpmestre rjpmestre force-pushed the mu-simplified_proxy_onboarding branch from 01af614 to a0952ea Compare February 21, 2025 13:58
@rjpmestre rjpmestre force-pushed the mu-simplified_proxy_onboarding branch 3 times, most recently from 7029847 to 3275d4a Compare February 24, 2025 11:19
@rjpmestre rjpmestre force-pushed the mu-simplified_proxy_onboarding branch from 8ec6f22 to 1ae01d7 Compare February 24, 2025 22:34
@rjpmestre rjpmestre force-pushed the mu-simplified_proxy_onboarding branch from 1ae01d7 to 84440a6 Compare February 24, 2025 22:37
@rjpmestre rjpmestre marked this pull request as ready for review February 24, 2025 23:08
@rjpmestre rjpmestre requested review from a team as code owners February 24, 2025 23:08
@rjpmestre rjpmestre requested review from cbbayburt and removed request for a team February 24, 2025 23:08
type SuccessType = boolean | undefined;

export const ContainerConfigMessages = (success: SuccessType, messagesIn: React.ReactNode[], loading: boolean) => {
if (success) {
Copy link
Member

Choose a reason for hiding this comment

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

This structure works, but feels a bit clunky with multiple branches all wrapped in a Messages.

Since Messages also returns null if there are no items, something along these lines would also work:

let items: MessageType[] = [];
if (success) {
  items = [{
    severity: "success",
    text: <p>{t("Proxy configuration successfully applied.")}</p>,
  }];
} else if ... { }

return <Messages items={items} />;

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks nice. As i based myself on the current proxy configuration solution I ended up neglecting that. ty!

@@ -0,0 +1,731 @@
import * as React from "react";
Copy link
Member

Choose a reason for hiding this comment

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

The code here looks mostly fine, but I would recommend breaking this up into multiple files to make it easier to digest, right now it's a pretty big bite. One option would be types and enums in one file, utils like stuff around file readers in another, etc, but I don't have a strong preference for how to chop this up.

}
};

const useDebounce = (callback: (...args: any) => any, timeoutMs: number) =>
Copy link
Member

Choose a reason for hiding this comment

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

Would recommend putting this in web/html/src/utils/hooks, and maybe also make it generic in case the types matter wherever we consume it later.

Suggested change
const useDebounce = (callback: (...args: any) => any, timeoutMs: number) =>
const useDebounce = <T extends (...args: any) => any>(callback: T, timeoutMs: number) =>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants