intermediateCAs, SSLCertPair proxyCertKey,
+ SSLCertPair caPair, String caPassword, SSLCertData certData, SSLCertManager certManager
+ );
+
+}
diff --git a/java/code/src/com/redhat/rhn/manager/system/proxycontainerconfig/ProxyContainerConfigCreate.java b/java/code/src/com/redhat/rhn/manager/system/proxycontainerconfig/ProxyContainerConfigCreateFacadeImpl.java
similarity index 93%
rename from java/code/src/com/redhat/rhn/manager/system/proxycontainerconfig/ProxyContainerConfigCreate.java
rename to java/code/src/com/redhat/rhn/manager/system/proxycontainerconfig/ProxyContainerConfigCreateFacadeImpl.java
index 0d866e8333d5..9c6c0342951b 100644
--- a/java/code/src/com/redhat/rhn/manager/system/proxycontainerconfig/ProxyContainerConfigCreate.java
+++ b/java/code/src/com/redhat/rhn/manager/system/proxycontainerconfig/ProxyContainerConfigCreateFacadeImpl.java
@@ -33,24 +33,23 @@
/**
* Main handler for creating proxy container configuration files.
* Three files should be created and compressed into a tarball:
- * - config.yaml : yaml configuration file that contains the server FQDN, max cache size, email, server version,
- * proxy FQDN, and root CA
- * - httpd.yaml : yaml file containing the system ID, server certificate, and server key
- * - ssh.yaml : yaml file containing the server SSH public key, proxy SSH key, and proxy SSH public key
- *
+ * - config.yaml : yaml configuration file that contains the server FQDN, max cache size, email, server version,
+ * proxy FQDN, and root CA
+ * - httpd.yaml : yaml file containing the system ID, server certificate, and server key
+ * - ssh.yaml : yaml file containing the server SSH public key, proxy SSH key, and proxy SSH public key
+ *
* This flow is divided into three main steps:
* - Acquire and validate all necessary data
* - Compute contents for files
* - Create tar archive with all necessary files
- *
*/
-public class ProxyContainerConfigCreate {
+public class ProxyContainerConfigCreateFacadeImpl implements ProxyContainerConfigCreateFacade {
private final List contextHandlerChain = new ArrayList<>();
/**
* Constructor
*/
- public ProxyContainerConfigCreate() {
+ public ProxyContainerConfigCreateFacadeImpl() {
this.contextHandlerChain.addAll(asList(
new ProxyContainerConfigCreateAcquisitor(),
new ProxyContainerConfigCreateGenerateFileMaps(),
@@ -81,6 +80,7 @@ public ProxyContainerConfigCreate() {
* @param certManager the SSLCertManager to use
* @return the tarball configuration file as a byte array
*/
+ @Override
public byte[] create(
SaltApi saltApi, SystemEntitlementManager systemEntitlementManager, User user,
String serverFqdn, String proxyFqdn, Integer proxyPort, Long maxCache, String email,
@@ -120,6 +120,7 @@ public byte[] create(
* @param certManager the SSLCertManager to use
* @return the configuration files as a map
*/
+ @Override
public Map createFiles(
SaltApi saltApi, SystemEntitlementManager systemEntitlementManager, User user,
String serverFqdn, String proxyFqdn, Integer proxyPort, Long maxCache, String email,
diff --git a/java/code/src/com/suse/manager/webui/controllers/ProxyConfigurationController.java b/java/code/src/com/suse/manager/webui/controllers/ProxyConfigurationController.java
index 1c25a34ebc1f..9991337c1956 100644
--- a/java/code/src/com/suse/manager/webui/controllers/ProxyConfigurationController.java
+++ b/java/code/src/com/suse/manager/webui/controllers/ProxyConfigurationController.java
@@ -26,37 +26,26 @@
import static spark.Spark.get;
import static spark.Spark.post;
-import com.redhat.rhn.GlobalInstanceHolder;
import com.redhat.rhn.common.RhnGeneralException;
import com.redhat.rhn.common.RhnRuntimeException;
-import com.redhat.rhn.common.conf.Config;
-import com.redhat.rhn.common.conf.ConfigDefaults;
-import com.redhat.rhn.common.db.datasource.DataResult;
-import com.redhat.rhn.common.validator.ValidatorResult;
import com.redhat.rhn.domain.server.Server;
-import com.redhat.rhn.domain.server.ServerFactory;
import com.redhat.rhn.domain.user.User;
-import com.redhat.rhn.frontend.dto.ShortSystemInfo;
-import com.redhat.rhn.manager.entitlement.EntitlementManager;
import com.redhat.rhn.manager.system.SystemManager;
-import com.redhat.rhn.manager.system.entitling.SystemEntitlementManager;
import com.suse.manager.api.ParseException;
import com.suse.manager.reactor.utils.LocalDateTimeISOAdapter;
import com.suse.manager.reactor.utils.OptionalTypeAdapterFactory;
-import com.suse.manager.utils.MinionServerUtils;
import com.suse.manager.webui.services.iface.SaltApi;
import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
import com.suse.manager.webui.utils.gson.ResultJson;
-import com.suse.manager.webui.utils.gson.SimpleMinionJson;
-import com.suse.proxy.ProxyConfigUtils;
import com.suse.proxy.ProxyContainerImagesEnum;
import com.suse.proxy.ProxyRegistryUtils;
import com.suse.proxy.ProxyRegistryUtilsImpl;
import com.suse.proxy.RegistryUrl;
-import com.suse.proxy.get.ProxyConfigGet;
-import com.suse.proxy.update.ProxyConfigUpdate;
-import com.suse.utils.Json;
+import com.suse.proxy.get.ProxyConfigGetFacade;
+import com.suse.proxy.get.ProxyConfigGetFacadeImpl;
+import com.suse.proxy.update.ProxyConfigUpdateFacade;
+import com.suse.proxy.update.ProxyConfigUpdateFacadeImpl;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -69,14 +58,10 @@
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
import spark.ModelAndView;
import spark.Request;
@@ -95,8 +80,9 @@ public class ProxyConfigurationController {
private final SystemManager systemManager;
private final SaltApi saltApi;
- private SystemEntitlementManager systemEntitlementManager = GlobalInstanceHolder.SYSTEM_ENTITLEMENT_MANAGER;
- private ProxyRegistryUtils proxyRegistryUtils = new ProxyRegistryUtilsImpl();
+ private final ProxyRegistryUtils proxyRegistryUtils;
+ private final ProxyConfigUpdateFacade proxyConfigUpdateFacade;
+ private final ProxyConfigGetFacade proxyConfigGetFacade;
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeISOAdapter())
@@ -105,14 +91,42 @@ public class ProxyConfigurationController {
.create();
/**
- * Create a new controller instance
+ * Create a new controller instance with default facades implementations
*
* @param systemManagerIn the system manager
* @param saltApiIn the salt API
*/
public ProxyConfigurationController(SystemManager systemManagerIn, SaltApi saltApiIn) {
+ this(
+ systemManagerIn,
+ saltApiIn,
+ new ProxyRegistryUtilsImpl(),
+ new ProxyConfigUpdateFacadeImpl(),
+ new ProxyConfigGetFacadeImpl()
+ );
+ }
+
+ /**
+ * Create a new controller instance
+ *
+ * @param systemManagerIn the system manager
+ * @param saltApiIn the salt API
+ * @param proxyRegistryUtilsIn the proxy registry utils
+ * @param proxyConfigUpdateFacadeIn the proxy config update facade
+ * @param proxyConfigGetFacadeIn the proxy config get facade
+ */
+ public ProxyConfigurationController(
+ SystemManager systemManagerIn,
+ SaltApi saltApiIn,
+ ProxyRegistryUtils proxyRegistryUtilsIn,
+ ProxyConfigUpdateFacade proxyConfigUpdateFacadeIn,
+ ProxyConfigGetFacade proxyConfigGetFacadeIn
+ ) {
this.systemManager = systemManagerIn;
this.saltApi = saltApiIn;
+ this.proxyRegistryUtils = proxyRegistryUtilsIn;
+ this.proxyConfigUpdateFacade = proxyConfigUpdateFacadeIn;
+ this.proxyConfigGetFacade = proxyConfigGetFacadeIn;
}
/**
@@ -123,7 +137,7 @@ public ProxyConfigurationController(SystemManager systemManagerIn, SaltApi saltA
*/
public void initRoutes(ProxyConfigurationController proxyController, JadeTemplateEngine jade) {
get("/manager/systems/details/proxy-config",
- withCsrfToken(withDocsLocale(withUserAndServer(this::proxyConfig))),
+ withCsrfToken(withDocsLocale(withUserAndServer(this::getProxyConfiguration))),
jade
);
post("/manager/systems/details/proxy-config", withUser(this::updateProxyConfiguration));
@@ -139,70 +153,8 @@ public void initRoutes(ProxyConfigurationController proxyController, JadeTemplat
* @param server the current server
* @return the ModelAndView object to render the page
*/
- public ModelAndView proxyConfig(Request request, Response response, User user, Server server) {
- Map data = new HashMap<>();
-
- // Handle the "Convert to Proxy" button: if server is convertible to proxy and doesn't have the proxy
- // entitlement, add it
- if (server.isConvertibleToProxy() && !server.hasProxyEntitlement()) {
- user.getOrg().getValidAddOnEntitlementsForOrg().stream()
- .filter(e -> e.getLabel().equalsIgnoreCase(EntitlementManager.PROXY_ENTITLED))
- .findFirst()
- .ifPresentOrElse(f -> {
- ValidatorResult vr = systemEntitlementManager.addEntitlementToServer(server, f);
- if (!vr.getErrors().isEmpty()) {
- LOG.error("Failed to add proxy entitlement to server. Server ID: {}, " +
- "hasProxyEntitlement: {}, isConvertibleToProxy: {}, errors: {}",
- server.getId(),
- server.hasProxyEntitlement(),
- server.isConvertibleToProxy(),
- vr.getErrors()
- );
- data.put("initFailMessage", "Failed to automatically add proxy entitlement to server.");
- }
- }, () -> {
- });
- }
-
- Map proxyConfigDataMap =
- ProxyConfigUtils.safeDataMapFromProxyConfig(new ProxyConfigGet().get(server));
- data.put("currentConfig", Json.GSON.toJson(proxyConfigDataMap));
- data.put("parents", Json.GSON.toJson(getElectableParents(user)));
- data.put("isUyuni", ConfigDefaults.get().isUyuni());
- return new ModelAndView(data, "templates/minion/proxy-config.jade");
- }
-
- /**
- * Get the list of electable parents to use as parent.
- *
- * @param user the current user
- * @return the list of electable parents
- */
- public List getElectableParents(User user) {
- DataResult dr = SystemManager.systemListShort(user, null);
- dr.elaborate();
- Set systems = Arrays.stream(dr.toArray())
- .map(system -> ((ShortSystemInfo) system).getId()).
- collect(Collectors.toSet());
-
- List electableParentsServers =
- ServerFactory.lookupByIdsAndOrg(systems, user.getOrg()).stream().filter(Server::isProxy).toList();
- List electableParentsAsSimpleMinionJson = new ArrayList<>(
- MinionServerUtils.filterSaltMinions(electableParentsServers)
- .map(SimpleMinionJson::fromMinionServer)
- .toList()
- );
-
- String localManagerFqdn = Config.get().getString(ConfigDefaults.SERVER_HOSTNAME);
- if (isAbsent(localManagerFqdn)) {
- if (LOG.isErrorEnabled()) {
- LOG.error("Could not determine the Server FQDN. Skipping it as a parent.");
- }
- return electableParentsAsSimpleMinionJson;
- }
-
- electableParentsAsSimpleMinionJson.add(new SimpleMinionJson(-1L, localManagerFqdn));
- return electableParentsAsSimpleMinionJson;
+ public ModelAndView getProxyConfiguration(Request request, Response response, User user, Server server) {
+ return new ModelAndView(proxyConfigGetFacade.getFormData(user, server), "templates/minion/proxy-config.jade");
}
/**
@@ -330,7 +282,7 @@ public String updateProxyConfiguration(Request request, Response response, User
GSON.fromJson(request.body(), new TypeToken() { }.getType());
try {
- new ProxyConfigUpdate().update(data, systemManager, saltApi, user);
+ proxyConfigUpdateFacade.update(data, systemManager, saltApi, user);
return result(response, ResultJson.success("Proxy configuration applied"));
}
catch (RhnRuntimeException e) {
diff --git a/java/code/src/com/suse/manager/webui/services/SaltServerActionService.java b/java/code/src/com/suse/manager/webui/services/SaltServerActionService.java
index 621f967f448a..554332f60ae6 100644
--- a/java/code/src/com/suse/manager/webui/services/SaltServerActionService.java
+++ b/java/code/src/com/suse/manager/webui/services/SaltServerActionService.java
@@ -221,7 +221,7 @@ public class SaltServerActionService {
public static final String APPSTREAMS_CONFIGURE = "appstreams.configure";
public static final String PARAM_APPSTREAMS_ENABLE = "param_appstreams_enable";
public static final String PARAM_APPSTREAMS_DISABLE = "param_appstreams_disable";
- public static final String APPLY_PROXY_CONFIG = "apply_proxy_config";
+ public static final String APPLY_PROXY_CONFIG = "proxy.apply_proxy_config";
/** SLS pillar parameter name for the list of update stack patch names. */
public static final String PARAM_UPDATE_STACK_PATCHES = "param_update_stack_patches";
diff --git a/java/code/src/com/suse/manager/webui/utils/gson/ProxyConfigUpdateJson.java b/java/code/src/com/suse/manager/webui/utils/gson/ProxyConfigUpdateJson.java
index 31a41099fafc..275ef3109d9f 100644
--- a/java/code/src/com/suse/manager/webui/utils/gson/ProxyConfigUpdateJson.java
+++ b/java/code/src/com/suse/manager/webui/utils/gson/ProxyConfigUpdateJson.java
@@ -19,7 +19,7 @@
import java.util.List;
/**
- * Represents the data sent from the UI to convert a minion into a proxy container configuration
+ * Represents the data received from the UI to convert a minion into a proxy container configuration
*/
public class ProxyConfigUpdateJson {
diff --git a/java/code/src/com/suse/proxy/ProxyConfigUtils.java b/java/code/src/com/suse/proxy/ProxyConfigUtils.java
index f9d0a8bbf53c..bca58d079171 100644
--- a/java/code/src/com/suse/proxy/ProxyConfigUtils.java
+++ b/java/code/src/com/suse/proxy/ProxyConfigUtils.java
@@ -30,20 +30,25 @@
import com.suse.proxy.model.ProxyConfig;
import com.suse.proxy.model.ProxyConfigImage;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* Utility class for handling Proxy Config
* Includes relevant constants and mappings from DTO / Pillar
+ * Pillar entries for the registry URLs will follow the example format:
+ * { ..., "registries": { "proxy-httpd": { "url": "https://.../proxy-httpd", "tag": "latest" }, ... } }
+ * names for the registry entries are defined in ProxyContainerImagesEnum image names
*/
public class ProxyConfigUtils {
- private static final String SAFE_SUFFIX = "_safe";
- private static final String CERTIFICATE_HEADER = "-----BEGIN CERTIFICATE-----\n";
-
-
private ProxyConfigUtils() {
throw new UnsupportedOperationException(NOT_INSTANTIABLE);
}
@@ -74,16 +79,11 @@ private ProxyConfigUtils() {
public static final String REGISTRY_BASE_URL = "registryBaseURL";
public static final String REGISTRY_BASE_TAG = "registryBaseTag";
-
- // Pillar entries
- // The pillar entries for the registry URLs will follow the example format:
- // { ..., "registries": { "proxy-httpd": { "url": "https://.../proxy-httpd", "tag": "latest" }, ... } }
- // names for the registry entries are defined in ProxyContainerImagesEnum image names
+ // Registry entries
public static final String PILLAR_REGISTRY_ENTRY = "registries";
public static final String PILLAR_REGISTRY_URL_ENTRY = "url";
public static final String PILLAR_REGISTRY_TAG_ENTRY = "tag";
-
/**
* Maps a minion pillar ProxyConfig
*
@@ -91,20 +91,23 @@ private ProxyConfigUtils() {
* @return the ProxyConfig
*/
public static ProxyConfig proxyConfigFromPillar(Pillar rootPillar) {
- Map pillar = rootPillar.getPillar();
ProxyConfig proxyConfig = new ProxyConfig();
- proxyConfig.setServerId((Long) pillar.get(SERVER_ID_FIELD));
- proxyConfig.setProxyFqdn(String.valueOf(pillar.get(PROXY_FQDN_FIELD)));
+ if (rootPillar == null || rootPillar.getPillar() == null) {
+ return proxyConfig;
+ }
+ Map pillar = rootPillar.getPillar();
- proxyConfig.setParentFqdn(String.valueOf(pillar.get(PARENT_FQDN_FIELD)));
+ proxyConfig.setServerId((Long) pillar.get(SERVER_ID_FIELD));
+ proxyConfig.setProxyFqdn(Objects.toString(pillar.get(PROXY_FQDN_FIELD), null));
+ proxyConfig.setParentFqdn(Objects.toString(pillar.get(PARENT_FQDN_FIELD), null));
proxyConfig.setProxyPort((Integer) pillar.get(PROXY_PORT_FIELD));
proxyConfig.setMaxCache((Integer) pillar.get(MAX_CACHE_FIELD));
- proxyConfig.setEmail(String.valueOf(pillar.get(EMAIL_FIELD)));
- proxyConfig.setRootCA(String.valueOf(pillar.get(ROOT_CA_FIELD)));
+ proxyConfig.setEmail(Objects.toString(pillar.get(EMAIL_FIELD), null));
+ proxyConfig.setRootCA(Objects.toString(pillar.get(ROOT_CA_FIELD), null));
proxyConfig.setIntermediateCAs((List) pillar.get(INTERMEDIATE_CAS_FIELD));
- proxyConfig.setProxyCert(String.valueOf(pillar.get(PROXY_CERT_FIELD)));
- proxyConfig.setProxyKey(String.valueOf(pillar.get(PROXY_KEY_FIELD)));
+ proxyConfig.setProxyCert(Objects.toString(pillar.get(PROXY_CERT_FIELD), null));
+ proxyConfig.setProxyKey(Objects.toString(pillar.get(PROXY_KEY_FIELD), null));
Map registries = (Map) pillar.get(PILLAR_REGISTRY_ENTRY);
@@ -162,12 +165,12 @@ public static ProxyConfig proxyConfigFromPillar(Pillar rootPillar) {
}
/**
- * Maps a ProxyConfig to a safe data map
+ * Maps a ProxyConfig
*
* @param proxyConfig the ProxyConfig
- * @return the safe data map
+ * @return the data map
*/
- public static Map safeDataMapFromProxyConfig(ProxyConfig proxyConfig) {
+ public static Map dataMapFromProxyConfig(ProxyConfig proxyConfig) {
Map data = new HashMap<>();
if (isAbsent(proxyConfig)) {
@@ -180,56 +183,69 @@ public static Map safeDataMapFromProxyConfig(ProxyConfig proxyCo
data.put(PROXY_PORT_FIELD, proxyConfig.getProxyPort());
data.put(MAX_CACHE_FIELD, proxyConfig.getMaxCache());
data.put(EMAIL_FIELD, proxyConfig.getEmail());
- data.put(ROOT_CA_FIELD + SAFE_SUFFIX, getSafeCertInput(proxyConfig.getRootCA()));
- data.put(PROXY_CERT_FIELD + SAFE_SUFFIX, getSafeCertInput(proxyConfig.getProxyCert()));
- data.put(PROXY_KEY_FIELD + SAFE_SUFFIX, getSafeCertInput(proxyConfig.getProxyKey()));
-
- List intermediateCAs = proxyConfig.getIntermediateCAs();
- if (isProvided(intermediateCAs)) {
- data.put(INTERMEDIATE_CAS_FIELD + SAFE_SUFFIX,
- intermediateCAs.stream()
- .map(ProxyConfigUtils::getSafeCertInput)
- .toList());
- }
+
+ data.put(USE_CERTS_MODE_FIELD, USE_CERTS_MODE_KEEP);
ProxyConfigImage httpdImage = proxyConfig.getHttpdImage();
+ ProxyConfigImage saltBrokerImage = proxyConfig.getSaltBrokerImage();
+ ProxyConfigImage squidImage = proxyConfig.getSquidImage();
+ ProxyConfigImage sshImage = proxyConfig.getSshImage();
+ ProxyConfigImage tftpdImage = proxyConfig.getTftpdImage();
+
+ // If all images are absent, we assume the source mode is RPM
+ if (allAbsent(httpdImage, saltBrokerImage, squidImage, sshImage, tftpdImage)) {
+ data.put(SOURCE_MODE_FIELD, ProxyConfigUtils.SOURCE_MODE_RPM);
+ return data;
+ }
+
+ // Otherwise we assume the source mode is registry
+ data.put(SOURCE_MODE_FIELD, ProxyConfigUtils.SOURCE_MODE_REGISTRY);
+
+ // Check if all images have the same tag and prefix
+ boolean isRegistryModeSimple =
+ ProxyConfigUtils.getCommonTag(httpdImage, saltBrokerImage, squidImage, sshImage, tftpdImage)
+ .map(tag ->
+ ProxyConfigUtils.getCommonPrefix(httpdImage, saltBrokerImage, squidImage, sshImage, tftpdImage)
+ .map(prefix -> {
+ data.put(REGISTRY_MODE, ProxyConfigUtils.REGISTRY_MODE_SIMPLE);
+ data.put(REGISTRY_BASE_TAG, tag);
+ data.put(REGISTRY_BASE_URL, prefix);
+ return true;
+ })
+ .orElse(false))
+ .orElse(false);
+
+ if (isRegistryModeSimple) {
+ return data;
+ }
+
+ // Otherwise registry mode is advanced
+ data.put(REGISTRY_MODE, ProxyConfigUtils.REGISTRY_MODE_ADVANCED);
if (isProvided(httpdImage)) {
data.put(PROXY_HTTPD.getUrlField(), httpdImage.getUrl());
data.put(PROXY_HTTPD.getTagField(), httpdImage.getTag());
}
- ProxyConfigImage saltBrokerImage = proxyConfig.getSaltBrokerImage();
if (isProvided(saltBrokerImage)) {
data.put(PROXY_SALT_BROKER.getUrlField(), saltBrokerImage.getUrl());
data.put(PROXY_SALT_BROKER.getTagField(), saltBrokerImage.getTag());
}
- ProxyConfigImage squidImage = proxyConfig.getSquidImage();
if (isProvided(squidImage)) {
data.put(PROXY_SQUID.getUrlField(), squidImage.getUrl());
data.put(PROXY_SQUID.getTagField(), squidImage.getTag());
}
- ProxyConfigImage sshImage = proxyConfig.getSshImage();
if (isProvided(sshImage)) {
data.put(PROXY_SSH.getUrlField(), sshImage.getUrl());
data.put(PROXY_SSH.getTagField(), sshImage.getTag());
}
- ProxyConfigImage tftpdImage = proxyConfig.getTftpdImage();
if (isProvided(tftpdImage)) {
data.put(PROXY_TFTPD.getUrlField(), tftpdImage.getUrl());
data.put(PROXY_TFTPD.getTagField(), tftpdImage.getTag());
}
- if (allAbsent(httpdImage, saltBrokerImage, squidImage, sshImage, tftpdImage)) {
- data.put(SOURCE_MODE_FIELD, ProxyConfigUtils.SOURCE_MODE_RPM);
- }
- else {
- data.put(SOURCE_MODE_FIELD, ProxyConfigUtils.SOURCE_MODE_REGISTRY);
- data.put(REGISTRY_MODE, ProxyConfigUtils.REGISTRY_MODE_ADVANCED);
- }
-
return data;
}
@@ -241,9 +257,13 @@ public static Map safeDataMapFromProxyConfig(ProxyConfig proxyCo
* @return a map of the data for the apply_proxy_config salt state file
*/
public static Map applyProxyConfigDataFromPillar(Pillar rootPillar) {
- Map pillar = rootPillar.getPillar();
Map data = new HashMap<>();
+ if (rootPillar == null || rootPillar.getPillar() == null || rootPillar.getPillar().isEmpty()) {
+ return data;
+ }
+ Map pillar = rootPillar.getPillar();
+
data.put(PARENT_FQDN_FIELD, pillar.get(PARENT_FQDN_FIELD));
data.put(PROXY_PORT_FIELD, pillar.get(PROXY_PORT_FIELD));
data.put(MAX_CACHE_FIELD, pillar.get(MAX_CACHE_FIELD));
@@ -274,17 +294,75 @@ public static Map applyProxyConfigDataFromPillar(Pillar rootPill
/**
- * Returns a preview of the certificate to be used as a (safe) preview
- * Truncates the input to the 10 characters.
+ * Verifies if all the images have the same (non-nullable) tag
*
- * @param cert the input string
- * @return the safe certificate input
+ * @param images the images to be verified
+ * @return the common tag if all images have the same tag, otherwise empty
*/
- public static String getSafeCertInput(String cert) {
- if (isAbsent(cert)) {
- return null;
+ public static Optional getCommonTag(ProxyConfigImage... images) {
+ if (isAbsent(images)) {
+ return Optional.empty();
}
- String content = cert.startsWith(CERTIFICATE_HEADER) ? cert.substring(CERTIFICATE_HEADER.length()) : cert;
- return content.length() <= 10 ? content : content.substring(0, 10) + "...";
+
+ Set tags = new HashSet<>();
+ for (ProxyConfigImage image : images) {
+ if (image == null || image.getTag() == null) {
+ return Optional.empty();
+ }
+ tags.add(image.getTag());
+ }
+
+ return tags.size() == 1 ? Optional.of(tags.iterator().next()) : Optional.empty();
}
+
+ /**
+ * Verifies if all the images url have a common prefix
+ *
+ * @param images the images to be verified
+ * @return the common prefix if all images have the same prefix, otherwise empty
+ */
+ public static Optional getCommonPrefix(ProxyConfigImage... images) {
+ if (isAbsent(images)) {
+ return Optional.empty();
+ }
+
+ Set allowedImageNames = Arrays.stream(ProxyContainerImagesEnum.values())
+ .map(ProxyContainerImagesEnum::getImageName)
+ .collect(Collectors.toSet());
+
+ Set imageUrlPrefixes = new HashSet<>();
+
+ for (ProxyConfigImage image : images) {
+ if (image == null || image.getUrl() == null) {
+ return Optional.empty();
+ }
+
+ String url = image.getUrl();
+ int lastSlash = url.lastIndexOf('/');
+
+ // If there is no slash, the image name is already invalid
+ if (lastSlash == -1) {
+ return Optional.empty();
+ }
+
+ // If the image name not provided or not in the allowed image names, then no common prefix
+ String imageName = url.substring(lastSlash + 1);
+ if (isAbsent(imageName) || !allowedImageNames.contains(imageName)) {
+ return Optional.empty();
+ }
+
+ // If the prefix is not provided, then no common prefix
+ String urlPrefix = url.substring(0, lastSlash + 1);
+ if (isAbsent(urlPrefix)) {
+ return Optional.empty();
+ }
+
+ // Add the prefix to a set
+ imageUrlPrefixes.add(urlPrefix);
+ }
+
+ // If the set does not contain exactly one entry, then no common prefix
+ return imageUrlPrefixes.size() == 1 ? Optional.of(imageUrlPrefixes.iterator().next()) : Optional.empty();
+ }
+
}
diff --git a/java/code/src/com/suse/proxy/get/ProxyConfigGet.java b/java/code/src/com/suse/proxy/get/ProxyConfigGetFacade.java
similarity index 60%
rename from java/code/src/com/suse/proxy/get/ProxyConfigGet.java
rename to java/code/src/com/suse/proxy/get/ProxyConfigGetFacade.java
index 3738903ec274..273cc82b67fa 100644
--- a/java/code/src/com/suse/proxy/get/ProxyConfigGet.java
+++ b/java/code/src/com/suse/proxy/get/ProxyConfigGetFacade.java
@@ -15,29 +15,31 @@
package com.suse.proxy.get;
-import static com.suse.proxy.ProxyConfigUtils.PROXY_PILLAR_CATEGORY;
-import static com.suse.utils.Predicates.isAbsent;
-
import com.redhat.rhn.domain.server.Server;
+import com.redhat.rhn.domain.user.User;
-import com.suse.proxy.ProxyConfigUtils;
import com.suse.proxy.model.ProxyConfig;
-public class ProxyConfigGet {
+import java.util.Map;
+
+/**
+ * Interface for operations that retrieve proxy configuration data.
+ */
+public interface ProxyConfigGetFacade {
/**
* Get the proxy configuration
* @param server the server
* @return the proxy configuration
*/
- public ProxyConfig get(Server server) {
- if (isAbsent(server)) {
- return null;
- }
- return server.asMinionServer()
- .flatMap(minionServer -> minionServer
- .getPillarByCategory(PROXY_PILLAR_CATEGORY)
- .map(ProxyConfigUtils::proxyConfigFromPillar))
- .orElse(null);
- }
+ ProxyConfig getProxyConfig(Server server);
+
+ /**
+ * Get the data to be rendered in the form
+ * @param user the user
+ * @param server the server
+ * @return the form data
+ */
+ Map getFormData(User user, Server server);
+
}
diff --git a/java/code/src/com/suse/proxy/get/ProxyConfigGetFacadeImpl.java b/java/code/src/com/suse/proxy/get/ProxyConfigGetFacadeImpl.java
new file mode 100644
index 000000000000..6a2c9a3b1019
--- /dev/null
+++ b/java/code/src/com/suse/proxy/get/ProxyConfigGetFacadeImpl.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.get;
+
+import static com.suse.proxy.ProxyConfigUtils.PROXY_PILLAR_CATEGORY;
+import static com.suse.utils.Predicates.isAbsent;
+import static java.util.Arrays.asList;
+
+import com.redhat.rhn.common.conf.ConfigDefaults;
+import com.redhat.rhn.domain.server.Server;
+import com.redhat.rhn.domain.user.User;
+
+import com.suse.proxy.ProxyConfigUtils;
+import com.suse.proxy.get.formdata.ProxyConfigGetFormDataAcquisitor;
+import com.suse.proxy.get.formdata.ProxyConfigGetFormDataContext;
+import com.suse.proxy.get.formdata.ProxyConfigGetFormDataContextHandler;
+import com.suse.proxy.get.formdata.ProxyConfigGetFormDataProxyInitializer;
+import com.suse.proxy.model.ProxyConfig;
+import com.suse.utils.Json;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class responsible for getting proxy configurations
+ */
+public class ProxyConfigGetFacadeImpl implements ProxyConfigGetFacade {
+ private final List getFormDataContextHandlerChain = new ArrayList<>();
+
+ /**
+ * Constructor
+ */
+ public ProxyConfigGetFacadeImpl() {
+ this.getFormDataContextHandlerChain.addAll(asList(
+ new ProxyConfigGetFormDataProxyInitializer(),
+ new ProxyConfigGetFormDataAcquisitor()
+ ));
+ }
+
+ /**
+ * Get the proxy configuration
+ *
+ * @param server the server
+ * @return the proxy configuration
+ */
+ @Override
+ public ProxyConfig getProxyConfig(Server server) {
+ if (isAbsent(server)) {
+ return null;
+ }
+ return server.asMinionServer()
+ .flatMap(minionServer -> minionServer
+ .getPillarByCategory(PROXY_PILLAR_CATEGORY)
+ .map(ProxyConfigUtils::proxyConfigFromPillar))
+ .orElse(null);
+ }
+
+ /**
+ * Get the data to be rendered in the form
+ *
+ * @param user the user
+ * @param server the server
+ * @return the form data
+ */
+ @Override
+ public Map getFormData(User user, Server server) {
+ ProxyConfigGetFormDataContext context = new ProxyConfigGetFormDataContext(user, server, this.getProxyConfig(server));
+
+ for (ProxyConfigGetFormDataContextHandler handler : getFormDataContextHandlerChain) {
+ handler.handle(context);
+ }
+
+ Map data = new HashMap<>();
+ data.put("currentConfig", Json.GSON.toJson(context.getProxyConfigAsMap()));
+ data.put("parents", Json.GSON.toJson(context.getElectableParentsFqdn()));
+ data.put("isUyuni", context.isUyuni());
+ data.put("initFailMessage", context.getInitFailMessage());
+
+ return data;
+ }
+
+
+
+}
diff --git a/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataAcquisitor.java b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataAcquisitor.java
new file mode 100644
index 000000000000..f8a1306fcf82
--- /dev/null
+++ b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataAcquisitor.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.get.formdata;
+
+import static com.suse.utils.Predicates.isAbsent;
+
+import com.redhat.rhn.common.conf.Config;
+import com.redhat.rhn.common.conf.ConfigDefaults;
+import com.redhat.rhn.common.db.datasource.DataResult;
+import com.redhat.rhn.frontend.dto.OrgProxyServer;
+import com.redhat.rhn.manager.system.SystemManager;
+
+import com.suse.proxy.ProxyConfigUtils;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * This step acquired the data required for the proxy configuration form
+ * But also sets a few defaults
+ */
+public class ProxyConfigGetFormDataAcquisitor implements ProxyConfigGetFormDataContextHandler {
+ private static final Logger LOG = LogManager.getLogger(ProxyConfigGetFormDataAcquisitor.class);
+
+ @Override
+ public void handle(ProxyConfigGetFormDataContext context) {
+ context.setProxyConfigAsMap(ProxyConfigUtils.dataMapFromProxyConfig(context.getProxyConfig()));
+ retrieveElectableParentsFqdn(context);
+ }
+
+ /**
+ * Retrieves the electable parents FQDNs
+ * Electable parents are all the proxy in the organization (except the current server) and also the local manager
+ *
+ * @param context the context
+ */
+ private void retrieveElectableParentsFqdn(ProxyConfigGetFormDataContext context) {
+ String localManagerFqdn = Config.get().getString(ConfigDefaults.SERVER_HOSTNAME);
+
+ DataResult orgProxyServers = SystemManager.listProxies(context.getUser().getOrg());
+ Set electableParents = orgProxyServers.stream()
+ .filter(s -> !Objects.equals(s.getId(), context.getServer().getId()))
+ .map(OrgProxyServer::getName)
+ .collect(Collectors.toSet());
+
+ if (isAbsent(localManagerFqdn)) {
+ LOG.error("Could not determine the Server FQDN. Skipping it as a parent.");
+ }
+ else {
+ electableParents.add(localManagerFqdn);
+ }
+
+ context.setElectableParentsFqdn(electableParents.stream().sorted().toList());
+ }
+}
diff --git a/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataContext.java b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataContext.java
new file mode 100644
index 000000000000..4abca9aa8597
--- /dev/null
+++ b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataContext.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.get.formdata;
+
+import com.redhat.rhn.common.conf.ConfigDefaults;
+import com.redhat.rhn.domain.server.Server;
+import com.redhat.rhn.domain.user.User;
+
+import com.suse.proxy.model.ProxyConfig;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class holds relevant data through the steps for acquiding the form data for the proxy config.
+ */
+public class ProxyConfigGetFormDataContext {
+
+ private final User user;
+ private final Server server;
+ private final ProxyConfig proxyConfig;
+
+ private Map proxyConfigAsMap;
+ private List electableParentsFqdn;
+ private String initFailMessage;
+
+ /**
+ * Constructor
+ *
+ * @param userIn the user
+ * @param serverIn the server
+ * @param proxyConfigIn the current proxy configuration
+ */
+ public ProxyConfigGetFormDataContext(User userIn, Server serverIn, ProxyConfig proxyConfigIn) {
+ this.user = userIn;
+ this.server = serverIn;
+ this.proxyConfig = proxyConfigIn;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public Server getServer() {
+ return server;
+ }
+
+ public Map getProxyConfigAsMap() {
+ return proxyConfigAsMap;
+ }
+
+ public void setProxyConfigAsMap(Map proxyConfigAsMapIn) {
+ proxyConfigAsMap = proxyConfigAsMapIn;
+ }
+
+ public List getElectableParentsFqdn() {
+ return electableParentsFqdn;
+ }
+
+ public void setElectableParentsFqdn(List electableParentsFqdnIn) {
+ electableParentsFqdn = electableParentsFqdnIn;
+ }
+
+ public boolean isUyuni() {
+ return ConfigDefaults.get().isUyuni();
+
+ }
+
+ public void setInitFailMessage(String initFailMessageIn) {
+ this.initFailMessage = initFailMessageIn;
+ }
+
+ public ProxyConfig getProxyConfig() {
+ return proxyConfig;
+ }
+
+ public String getInitFailMessage() {
+ return initFailMessage;
+ }
+}
\ No newline at end of file
diff --git a/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataContextHandler.java b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataContextHandler.java
new file mode 100644
index 000000000000..9de38aa22f97
--- /dev/null
+++ b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataContextHandler.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.get.formdata;
+
+public interface ProxyConfigGetFormDataContextHandler {
+ /**
+ * Handles a step in saving a proxy configuration
+ * @param context the context
+ */
+ void handle(ProxyConfigGetFormDataContext context);
+}
diff --git a/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataProxyInitializer.java b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataProxyInitializer.java
new file mode 100644
index 000000000000..4a6dde1a478e
--- /dev/null
+++ b/java/code/src/com/suse/proxy/get/formdata/ProxyConfigGetFormDataProxyInitializer.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.get.formdata;
+
+import com.redhat.rhn.GlobalInstanceHolder;
+import com.redhat.rhn.common.validator.ValidatorResult;
+import com.redhat.rhn.domain.server.ProxyInfo;
+import com.redhat.rhn.domain.server.Server;
+import com.redhat.rhn.manager.entitlement.EntitlementManager;
+import com.redhat.rhn.manager.system.SystemManager;
+import com.redhat.rhn.manager.system.entitling.SystemEntitlementManager;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Ensures the correct behavior of the "Convert to Proxy" button.
+ * If the server is convertible to a proxy and:
+ * a) Does not have the proxy entitlement, it is added.
+ * b) Does not have a {@link ProxyInfo}, it is created.
+ */
+public class ProxyConfigGetFormDataProxyInitializer implements ProxyConfigGetFormDataContextHandler {
+ private static final Logger LOG = LogManager.getLogger(ProxyConfigGetFormDataProxyInitializer.class);
+ private static final SystemEntitlementManager SYSTEM_ENTITLEMENT_MANAGER =
+ GlobalInstanceHolder.SYSTEM_ENTITLEMENT_MANAGER;
+
+ @Override
+ public void handle(ProxyConfigGetFormDataContext context) {
+ Server server = context.getServer();
+ if (!server.isConvertibleToProxy()) {
+ return;
+ }
+
+ ensureServerHasProxyInfo(server);
+ if (!ensureServerHasProxyEntitlement(context)) {
+ context.setInitFailMessage("Failed to add proxy entitlement to server.");
+ }
+ }
+
+ /**
+ * Ensures that the server has a {@link ProxyInfo}.
+ *
+ * @param server the server
+ */
+ public void ensureServerHasProxyInfo(Server server) {
+ if (server.getProxyInfo() != null) {
+ return;
+ }
+
+ ProxyInfo proxyInfo = new ProxyInfo();
+ proxyInfo.setServer(server);
+ server.setProxyInfo(proxyInfo);
+ SystemManager.updateSystemOverview(server.getId());
+ }
+
+ private boolean ensureServerHasProxyEntitlement(ProxyConfigGetFormDataContext context) {
+ Server server = context.getServer();
+ if (server.hasProxyEntitlement()) {
+ return true;
+ }
+
+ if (!SYSTEM_ENTITLEMENT_MANAGER.canEntitleServer(server, EntitlementManager.PROXY)) {
+ LOG.error("Server is not entitleable for proxy entitlement. ID: {}", server.getId());
+ return false;
+ }
+
+ ValidatorResult result = SYSTEM_ENTITLEMENT_MANAGER.addEntitlementToServer(server, EntitlementManager.PROXY);
+ if (!result.getErrors().isEmpty()) {
+ LOG.error("Failed to add proxy entitlement to server. ID: {}, Errors: {}",
+ server.getId(), result.getErrors());
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/java/code/src/com/suse/proxy/model/ProxyConfig.java b/java/code/src/com/suse/proxy/model/ProxyConfig.java
index a1c300b1290d..23a1a3a973c0 100644
--- a/java/code/src/com/suse/proxy/model/ProxyConfig.java
+++ b/java/code/src/com/suse/proxy/model/ProxyConfig.java
@@ -17,6 +17,9 @@
import java.util.List;
+/**
+ * Class representing the proxy configuration
+ */
public class ProxyConfig {
private Long serverId;
diff --git a/java/code/src/com/suse/proxy/model/ProxyConfigImage.java b/java/code/src/com/suse/proxy/model/ProxyConfigImage.java
index d07426b4b1c3..506c4fade78e 100644
--- a/java/code/src/com/suse/proxy/model/ProxyConfigImage.java
+++ b/java/code/src/com/suse/proxy/model/ProxyConfigImage.java
@@ -15,6 +15,9 @@
package com.suse.proxy.model;
+/**
+ * Class representing the proxy configuration image
+ */
public class ProxyConfigImage {
private String url;
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateAcquisitorTest.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateAcquisitorTest.java
index c22797b23291..18ebd6bf7556 100644
--- a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateAcquisitorTest.java
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateAcquisitorTest.java
@@ -15,5 +15,518 @@
package com.suse.proxy.test;
-public class ProxyConfigUpdateAcquisitorTest {
+import static com.suse.proxy.ProxyConfigUtils.REGISTRY_MODE_SIMPLE;
+import static com.suse.proxy.ProxyConfigUtils.SOURCE_MODE_REGISTRY;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_ADMIN_MAIL;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_INTERMEDIATE_CA_1;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_INTERMEDIATE_CA_2;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_MAX_CACHE;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PARENT_FQDN;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_CERT;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_FQDN;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_KEY;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_PORT;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_ROOT_CA;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_SERVER_ID;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_TAG;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_URL_PREFIX;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.assertExpectedErrors;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.getDummyTag;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.getDummyUrl;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.redhat.rhn.domain.server.MinionServer;
+import com.redhat.rhn.domain.server.Pillar;
+import com.redhat.rhn.domain.server.Server;
+import com.redhat.rhn.domain.server.ServerConstants;
+import com.redhat.rhn.domain.server.ServerFactory;
+import com.redhat.rhn.domain.server.test.MinionServerFactoryTest;
+import com.redhat.rhn.domain.server.test.ServerFactoryTest;
+import com.redhat.rhn.manager.entitlement.EntitlementManager;
+import com.redhat.rhn.manager.formula.FormulaMonitoringManager;
+import com.redhat.rhn.manager.system.ServerGroupManager;
+import com.redhat.rhn.manager.system.entitling.SystemEntitlementManager;
+import com.redhat.rhn.manager.system.entitling.SystemEntitler;
+import com.redhat.rhn.manager.system.entitling.SystemUnentitler;
+import com.redhat.rhn.testing.BaseTestCaseWithUser;
+import com.redhat.rhn.testing.TestUtils;
+
+import com.suse.manager.webui.services.iface.MonitoringManager;
+import com.suse.manager.webui.services.iface.SaltApi;
+import com.suse.manager.webui.services.test.TestSaltApi;
+import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
+import com.suse.proxy.ProxyConfigUtils;
+import com.suse.proxy.ProxyContainerImagesEnum;
+import com.suse.proxy.RegistryUrl;
+import com.suse.proxy.model.ProxyConfig;
+import com.suse.proxy.update.ProxyConfigUpdateAcquisitor;
+import com.suse.proxy.update.ProxyConfigUpdateContext;
+import com.suse.utils.Json;
+
+import org.jmock.imposters.ByteBuddyClassImposteriser;
+import org.jmock.junit5.JUnit5Mockery;
+import org.jmock.lib.concurrent.Synchroniser;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Tests for the {@link ProxyConfigUpdateAcquisitor} class
+ */
+@ExtendWith(JUnit5Mockery.class)
+public class ProxyConfigUpdateAcquisitorTest extends BaseTestCaseWithUser {
+
+ public static final String DUMMY_REPLACE_ROOT_CA = "replace_rootCA";
+ public static final String DUMMY_REPLACE_INTERMEDIATE_CA_1 = "replace_intermediateCA1";
+ public static final String DUMMY_REPLACE_INTERMEDIATE_CA_2 = "replace_intermediateCA2";
+ public static final String DUMMY_REPLACE_PROXY_CERT = "replace_proxyCert";
+ public static final String DUMMY_REPLACE_PROXY_KEY = "replace_proxyKey";
+
+ private final SaltApi saltApi = new TestSaltApi();
+ private final ServerGroupManager serverGroupManager = new ServerGroupManager(saltApi);
+ private final MonitoringManager monitoringManager = new FormulaMonitoringManager(saltApi);
+ private final SystemEntitlementManager systemEntitlementManager = new SystemEntitlementManager(
+ new SystemUnentitler(monitoringManager, serverGroupManager),
+ new SystemEntitler(saltApi, monitoringManager, serverGroupManager)
+ );
+
+ @SuppressWarnings({"java:S1171", "java:S3599"})
+ @RegisterExtension
+ protected final JUnit5Mockery context = new JUnit5Mockery() {{
+ setThreadingPolicy(new Synchroniser());
+ }};
+
+ @Override
+ @BeforeEach
+ public void setUp() throws Exception {
+ super.setUp();
+ context.setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
+ }
+
+ /**
+ * Test a scenario where provided {@link ProxyConfigUpdateJson} request is empty
+ */
+ @Test
+ public void testBlankRequest() {
+ ProxyConfigUpdateJson request = Json.GSON.fromJson("{}", ProxyConfigUpdateJson.class);
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+ // acquireProxyMinion
+ assertNull(proxyConfigUpdateContext.getProxyMinion());
+ assertNull(proxyConfigUpdateContext.getProxyFqdn());
+ assertNull(proxyConfigUpdateContext.getProxyConfig());
+ // acquireCertificates
+ assertNull(proxyConfigUpdateContext.getProxyCert());
+ assertNull(proxyConfigUpdateContext.getIntermediateCAs());
+ assertNull(proxyConfigUpdateContext.getProxyCert());
+ assertNull(proxyConfigUpdateContext.getProxyKey());
+ // acquireParentServer
+ assertNull(proxyConfigUpdateContext.getParentServer());
+ // buildRegistryUrls
+ assertTrue(proxyConfigUpdateContext.getRegistryUrls().isEmpty());
+
+
+ }
+
+ /**
+ * Test scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request is provided with all fields filled;
+ * - No data is acquired.
+ */
+ @Test
+ public void testFullRequestNoAcquisitions() {
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
+ .serverId(DUMMY_SERVER_ID)
+ .parentFqdn(DUMMY_ADMIN_MAIL)
+ .proxyPort(DUMMY_PROXY_PORT)
+ .maxCache(DUMMY_MAX_CACHE)
+ .email(DUMMY_ADMIN_MAIL)
+ .replaceCerts(
+ DUMMY_ROOT_CA,
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ DUMMY_PROXY_CERT,
+ DUMMY_PROXY_KEY
+ )
+ .sourceRegistryAdvanced(
+ getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD),
+ getDummyTag(ProxyContainerImagesEnum.PROXY_HTTPD),
+ getDummyUrl(ProxyContainerImagesEnum.PROXY_SALT_BROKER),
+ getDummyTag(ProxyContainerImagesEnum.PROXY_SALT_BROKER),
+ getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID),
+ getDummyTag(ProxyContainerImagesEnum.PROXY_SQUID),
+ getDummyUrl(ProxyContainerImagesEnum.PROXY_SSH),
+ getDummyTag(ProxyContainerImagesEnum.PROXY_SSH),
+ getDummyUrl(ProxyContainerImagesEnum.PROXY_TFTPD),
+ getDummyTag(ProxyContainerImagesEnum.PROXY_TFTPD)
+ )
+ .build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+ // acquireProxyMinion
+ assertNull(proxyConfigUpdateContext.getProxyMinion());
+ assertNull(proxyConfigUpdateContext.getProxyFqdn());
+ assertNull(proxyConfigUpdateContext.getProxyConfig());
+ // acquireCertificates
+ assertEquals(DUMMY_PROXY_CERT, proxyConfigUpdateContext.getProxyCert());
+ assertEquals(DUMMY_ROOT_CA, proxyConfigUpdateContext.getRootCA());
+ assertEquals(
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ proxyConfigUpdateContext.getIntermediateCAs()
+ );
+ assertEquals(DUMMY_PROXY_CERT, proxyConfigUpdateContext.getProxyCert());
+ // acquireParentServer
+ assertNull(proxyConfigUpdateContext.getParentServer());
+ // buildRegistryUrls
+ assertEquals(ProxyContainerImagesEnum.values().length, proxyConfigUpdateContext.getRegistryUrls().size());
+ for (ProxyContainerImagesEnum image : ProxyContainerImagesEnum.values()) {
+ assertTrue(proxyConfigUpdateContext.getRegistryUrls().containsKey(image));
+ RegistryUrl registryUrl = proxyConfigUpdateContext.getRegistryUrls().get(image);
+ assertEquals(DUMMY_TAG + "_" + image.getImageName(), registryUrl.getTag());
+ assertEquals(DUMMY_URL_PREFIX + image.getImageName(), registryUrl.getUrl());
+ }
+ }
+
+ /**
+ * Test acquireProxyMinion in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data;
+ * - All minion data is acquirable.
+ */
+ @Test
+ public void testAcquireProxyMinionWhenSuccessfulAcquisitions() {
+ // minion setup
+ MinionServer minion = MinionServerFactoryTest.createTestMinionServer(user);
+ minion.setServerArch(ServerFactory.lookupServerArchByLabel("x86_64-redhat-linux"));
+ minion.addFqdn(DUMMY_PROXY_FQDN);
+ systemEntitlementManager.addEntitlementToServer(minion, EntitlementManager.PROXY);
+ Pillar pillar = new Pillar(ProxyConfigUtils.PROXY_PILLAR_CATEGORY, new HashMap<>(), minion);
+ pillar.add(ProxyConfigUtils.PROXY_FQDN_FIELD, DUMMY_PROXY_FQDN);
+ pillar.add(ProxyConfigUtils.PARENT_FQDN_FIELD, DUMMY_PARENT_FQDN);
+ minion.addPillar(pillar);
+ TestUtils.saveAndFlush(minion);
+
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder().serverId(minion.getId()).build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // acquireProxyMinion
+ assertNotNull(proxyConfigUpdateContext.getProxyMinion());
+ assertEquals(DUMMY_PROXY_FQDN, proxyConfigUpdateContext.getProxyFqdn());
+ ProxyConfig proxyConfig = proxyConfigUpdateContext.getProxyConfig();
+ assertNotNull(proxyConfig);
+ assertEquals(DUMMY_PROXY_FQDN, proxyConfig.getProxyFqdn());
+ assertEquals(DUMMY_PARENT_FQDN, proxyConfig.getParentFqdn());
+ }
+
+ /**
+ * Test acquireCertificates in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data, indicating we want to keep existing certificates;
+ * - Minion has certificates saved in its pillar.
+ * Expects the {@link ProxyConfigUpdateContext} to keep the existing ones in the pillars, discarding certificates
+ * data provided in {@link ProxyConfigUpdateJson}.
+ */
+ @Test
+ public void testAcquireCertificatesKeepWhenSuccessfulRetrieveCertificates() {
+ // minion setup
+ MinionServer minion = MinionServerFactoryTest.createTestMinionServer(user);
+ systemEntitlementManager.addEntitlementToServer(minion, EntitlementManager.PROXY);
+ Pillar pillar = new Pillar(ProxyConfigUtils.PROXY_PILLAR_CATEGORY, new HashMap<>(), minion);
+ pillar.add(ProxyConfigUtils.ROOT_CA_FIELD, DUMMY_ROOT_CA);
+ pillar.add(ProxyConfigUtils.INTERMEDIATE_CAS_FIELD, List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2));
+ pillar.add(ProxyConfigUtils.PROXY_CERT_FIELD, DUMMY_PROXY_CERT);
+ pillar.add(ProxyConfigUtils.PROXY_KEY_FIELD, DUMMY_PROXY_KEY);
+ minion.addPillar(pillar);
+ TestUtils.saveAndFlush(minion);
+
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
+ .serverId(minion.getId())
+ .keepCerts(
+ DUMMY_REPLACE_ROOT_CA,
+ List.of(DUMMY_REPLACE_INTERMEDIATE_CA_1, DUMMY_REPLACE_INTERMEDIATE_CA_2),
+ DUMMY_REPLACE_PROXY_CERT,
+ DUMMY_REPLACE_PROXY_KEY
+ ).build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // acquireCertificates
+ assertEquals(DUMMY_ROOT_CA, proxyConfigUpdateContext.getRootCA());
+ assertEquals(
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ proxyConfigUpdateContext.getIntermediateCAs()
+ );
+ assertEquals(DUMMY_PROXY_CERT, proxyConfigUpdateContext.getProxyCert());
+ assertEquals(DUMMY_PROXY_KEY, proxyConfigUpdateContext.getProxyKey());
+ }
+
+ /**
+ * Test acquireCertificates in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data, indicating we want to keep existing certificates;
+ * - Minion does NOT have proxy pillars in DB.
+ * Expects the {@link ProxyConfigUpdateContext} certificates data to be null.
+ */
+ @Test
+ public void testAcquireCertificatesKeepWhenFailRetrieveCertificates() {
+ // minion setup
+ MinionServer minion = MinionServerFactoryTest.createTestMinionServer(user);
+ systemEntitlementManager.addEntitlementToServer(minion, EntitlementManager.PROXY);
+ TestUtils.saveAndFlush(minion);
+
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
+ .serverId(minion.getId())
+ .keepCerts(
+ DUMMY_REPLACE_ROOT_CA,
+ List.of(DUMMY_REPLACE_INTERMEDIATE_CA_1, DUMMY_REPLACE_INTERMEDIATE_CA_2),
+ DUMMY_REPLACE_PROXY_CERT,
+ DUMMY_REPLACE_PROXY_KEY
+ ).build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // acquireCertificates
+ assertNull(proxyConfigUpdateContext.getRootCA());
+ assertNull(proxyConfigUpdateContext.getIntermediateCAs());
+ assertNull(proxyConfigUpdateContext.getProxyCert());
+ assertNull(proxyConfigUpdateContext.getProxyKey());
+ }
+
+ /**
+ * Test acquireCertificates in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data, indicating we want to replace certificates;
+ * - Minion has certificates saved in its pillar.
+ * Expects the {@link ProxyConfigUpdateContext} to replace certificates data.
+ */
+ @Test
+ public void testAcquireCertificatesReplaceWhenSuccessfulRetrieveCertificates() {
+ // minion setup
+ MinionServer minion = MinionServerFactoryTest.createTestMinionServer(user);
+ systemEntitlementManager.addEntitlementToServer(minion, EntitlementManager.PROXY);
+ Pillar pillar = new Pillar(ProxyConfigUtils.PROXY_PILLAR_CATEGORY, new HashMap<>(), minion);
+ pillar.add(ProxyConfigUtils.ROOT_CA_FIELD, DUMMY_ROOT_CA);
+ pillar.add(ProxyConfigUtils.INTERMEDIATE_CAS_FIELD, List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2));
+ pillar.add(ProxyConfigUtils.PROXY_CERT_FIELD, DUMMY_PROXY_CERT);
+ pillar.add(ProxyConfigUtils.PROXY_KEY_FIELD, DUMMY_PROXY_KEY);
+ minion.addPillar(pillar);
+ TestUtils.saveAndFlush(minion);
+
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
+ .serverId(minion.getId())
+ .replaceCerts(
+ DUMMY_REPLACE_ROOT_CA,
+ List.of(DUMMY_REPLACE_INTERMEDIATE_CA_1, DUMMY_REPLACE_INTERMEDIATE_CA_2),
+ DUMMY_REPLACE_PROXY_CERT,
+ DUMMY_REPLACE_PROXY_KEY
+ ).build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // acquireCertificates
+ assertEquals(DUMMY_REPLACE_ROOT_CA, proxyConfigUpdateContext.getRootCA());
+ assertEquals(
+ List.of(DUMMY_REPLACE_INTERMEDIATE_CA_1, DUMMY_REPLACE_INTERMEDIATE_CA_2),
+ proxyConfigUpdateContext.getIntermediateCAs()
+ );
+ assertEquals(DUMMY_REPLACE_PROXY_CERT, proxyConfigUpdateContext.getProxyCert());
+ assertEquals(DUMMY_REPLACE_PROXY_KEY, proxyConfigUpdateContext.getProxyKey());
+ }
+
+
+ /**
+ * Test acquireParentServer in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data (ie. parent fqdn);
+ * - Parent server is reachable using the provided fqdn.
+ */
+ @Test
+ public void testAcquireParentServerWhenSuccessfulRetrieveServer() {
+ // parent server setup
+ Server parent = ServerFactoryTest.createTestServer(user, true,
+ ServerConstants.getServerGroupTypeSaltEntitled(),
+ ServerFactoryTest.TYPE_SERVER_MGR);
+ parent.addFqdn(DUMMY_PARENT_FQDN);
+
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder().parentFqdn(DUMMY_PARENT_FQDN).build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // acquireParentServer
+ assertEquals(parent, proxyConfigUpdateContext.getParentServer());
+ }
+
+ /**
+ * Test acquireParentServer in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data (ie. parent fqdn);
+ * - Parent server is not found using the provided fqdn.
+ */
+ @Test
+ public void testAcquireParentServerWhenFailRetrieveServer() {
+ // parent server setup
+ Server parent = ServerFactoryTest.createTestServer(user, true,
+ ServerConstants.getServerGroupTypeSaltEntitled(),
+ ServerFactoryTest.TYPE_SERVER_MGR);
+ parent.addFqdn(DUMMY_PARENT_FQDN);
+
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder().parentFqdn("not.existent.com").build();
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // acquireParentServer
+ assertNull(proxyConfigUpdateContext.getParentServer());
+ }
+
+ /**
+ * Test buildRegistryUrls in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data, indicating we want to use registries,
+ * providing a common registry and tag for all images.
+ */
+ @Test
+ public void testBuildRegistryUrlsWhenSimpleRegistry() {
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
+ .sourceMode(SOURCE_MODE_REGISTRY)
+ .registryMode(REGISTRY_MODE_SIMPLE)
+ .registryBaseURL("http://suse.com/common/image")
+ .registryBaseTag(DUMMY_TAG)
+ .build();
+
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // buildRegistryUrls
+ assertEquals(ProxyContainerImagesEnum.values().length, proxyConfigUpdateContext.getRegistryUrls().size());
+ for (ProxyContainerImagesEnum image : ProxyContainerImagesEnum.values()) {
+ assertTrue(proxyConfigUpdateContext.getRegistryUrls().containsKey(image));
+ RegistryUrl registryUrl = proxyConfigUpdateContext.getRegistryUrls().get(image);
+ assertEquals(DUMMY_TAG, registryUrl.getTag());
+ assertEquals("http://suse.com/common/image/" + image.getImageName(), registryUrl.getUrl());
+ }
+ }
+
+ /**
+ * Test buildRegistryUrls in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data, indicating we want to use registries,
+ * providing a common registry and tag for all images.
+ */
+ @Test
+ public void testFailBuildRegistryUrlsWhenSimpleRegistryWithBadUrl() {
+ final String[] expectedErrorMessages = {"Invalid Registry URL"};
+ ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
+ .sourceMode(SOURCE_MODE_REGISTRY)
+ .registryMode(REGISTRY_MODE_SIMPLE)
+ .registryBaseURL("http://invalid-url^") // This should cause URISyntaxException
+ .registryBaseTag(DUMMY_TAG)
+ .build();
+
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ //
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+ assertExpectedErrors(expectedErrorMessages, proxyConfigUpdateContext);
+ }
+
+ /**
+ * Test buildRegistryUrls in a scenario with following conditions:
+ * - {@link ProxyConfigUpdateJson} request provides required data, indicating we want to use registries and
+ * specifying for each one its url and tag.
+ */
+ @Test
+ public void testBuildRegistryUrlsWhenAdvancedRegistry() {
+ ProxyConfigUpdateJson request = getFullRequest().build();
+
+ ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
+
+ // execution
+ new ProxyConfigUpdateAcquisitor().handle(proxyConfigUpdateContext);
+
+ //assertions
+ assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
+
+ // buildRegistryUrls
+ assertEquals(ProxyContainerImagesEnum.values().length, proxyConfigUpdateContext.getRegistryUrls().size());
+ for (ProxyContainerImagesEnum image : ProxyContainerImagesEnum.values()) {
+ assertTrue(proxyConfigUpdateContext.getRegistryUrls().containsKey(image));
+ RegistryUrl registryUrl = proxyConfigUpdateContext.getRegistryUrls().get(image);
+ assertEquals(image.getImageName() + "-latest", registryUrl.getTag());
+ assertEquals("http://suse.com/" + image.getImageName(), registryUrl.getUrl());
+ }
+ }
+
+
+ /**
+ * Creates a request with all fields filled.
+ * Considers replacing certs and using registries.
+ *
+ * @return the request builder
+ */
+ private ProxyConfigUpdateJsonBuilder getFullRequest() {
+ return new ProxyConfigUpdateJsonBuilder()
+ .serverId(DUMMY_SERVER_ID)
+ .parentFqdn(DUMMY_PARENT_FQDN)
+ .proxyPort(DUMMY_PROXY_PORT)
+ .maxCache(DUMMY_MAX_CACHE)
+ .email(DUMMY_ADMIN_MAIL)
+ .replaceCerts(
+ DUMMY_ROOT_CA,
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ DUMMY_PROXY_CERT,
+ DUMMY_PROXY_KEY
+ ).sourceRegistryAdvanced(
+ "http://suse.com/proxy-httpd", "proxy-httpd-latest",
+ "http://suse.com/proxy-salt-broker", "proxy-salt-broker-latest",
+ "http://suse.com/proxy-squid", "proxy-squid-latest",
+ "http://suse.com/proxy-ssh", "proxy-ssh-latest",
+ "http://suse.com/proxy-tftpd", "proxy-tftpd-latest"
+ );
+ }
+
}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateFacadeImplTest.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateFacadeImplTest.java
new file mode 100644
index 000000000000..19590822ae2c
--- /dev/null
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateFacadeImplTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import com.redhat.rhn.common.RhnGeneralException;
+import com.redhat.rhn.testing.MockObjectTestCase;
+
+import com.suse.proxy.update.ProxyConfigUpdateFacadeImpl;
+import com.suse.proxy.update.ProxyConfigUpdateContext;
+import com.suse.proxy.update.ProxyConfigUpdateContextHandler;
+
+import org.jmock.junit5.JUnit5Mockery;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Tests for the ProxyConfigUpdate class
+ */
+@ExtendWith(JUnit5Mockery.class)
+public class ProxyConfigUpdateFacadeImplTest extends MockObjectTestCase {
+
+ /**
+ * Tests the success case when all handlers are successful
+ */
+ @Test
+ public void testSuccessWhenUpdate() throws NoSuchFieldException, IllegalAccessException {
+ ProxyConfigUpdateContextHandler okHandler1 = new OkHandler();
+ ProxyConfigUpdateContextHandler okHandler2 = new OkHandler();
+ ProxyConfigUpdateContextHandler okHandler3 = new OkHandler();
+
+ ProxyConfigUpdateFacadeImpl proxyConfigUpdate = new ProxyConfigUpdateFacadeImpl();
+ replaceHandlers(proxyConfigUpdate, List.of(okHandler1, okHandler2, okHandler3));
+
+ proxyConfigUpdate.update(null, null, null, null);
+ }
+
+ /**
+ * Tests a scenario where there are 3 handlers.
+ * The first one is successful;
+ * The second one registers with 3 errors;
+ * The third one registers with 2 errors.
+ * It is expected that the process halts after the second handler and the errors are reported in a
+ * {@link RhnGeneralException} with the expected error messages.
+ */
+ @Test
+ public void testFailWhenUpdateWithError() throws NoSuchFieldException, IllegalAccessException {
+ final String[] expectedErrorMessages = {"oops", "three", "errors?"};
+
+ ProxyConfigUpdateContextHandler okHandler = new OkHandler();
+ ProxyConfigUpdateContextHandler failingHandler = new FailingHandler();
+ ProxyConfigUpdateContextHandler anotherFailingHandler = new AnotherFailingHandler();
+
+ ProxyConfigUpdateFacadeImpl proxyConfigUpdate = new ProxyConfigUpdateFacadeImpl();
+ replaceHandlers(proxyConfigUpdate, List.of(okHandler, failingHandler, anotherFailingHandler));
+
+ try {
+ proxyConfigUpdate.update(null, null, null, null);
+ fail("Expected RhnGeneralException to be thrown");
+ }
+ catch (RhnGeneralException e) {
+ Assertions.assertEquals(expectedErrorMessages.length, e.getErrorMessages().length);
+ for (String expectedErrorMessage : expectedErrorMessages) {
+ assertTrue(Arrays.asList(e.getErrorMessages()).contains(expectedErrorMessage));
+ }
+ }
+ }
+
+ /**
+ * A handler that does nothing, mocking a valid step
+ */
+ public static class OkHandler implements ProxyConfigUpdateContextHandler {
+ @Override
+ public void handle(ProxyConfigUpdateContext context) {
+ // does nothing
+ }
+ }
+
+ /**
+ * A handler that registers three errors, mocking an invalid step
+ */
+ public static class FailingHandler implements ProxyConfigUpdateContextHandler {
+ @Override
+ public void handle(ProxyConfigUpdateContext context) {
+ context.getErrorReport().register("oops");
+ context.getErrorReport().register("three");
+ context.getErrorReport().register("errors?");
+ }
+ }
+
+ /**
+ * Another handler that registers errors, mocking an invalid step
+ */
+ public static class AnotherFailingHandler implements ProxyConfigUpdateContextHandler {
+ @Override
+ public void handle(ProxyConfigUpdateContext context) {
+ context.getErrorReport().register("more");
+ context.getErrorReport().register("errors!");
+ }
+ }
+
+ /**
+ * Replaces the handlers in the ProxyConfigUpdate chain of responsibility private field
+ * @param proxyConfigUpdate the ProxyConfigUpdate instance
+ * @param handlers the new handlers
+ * @throws NoSuchFieldException if the field is not found
+ * @throws IllegalAccessException if the field cannot be accessed
+ */
+ @SuppressWarnings("squid:S3011")
+ private void replaceHandlers(ProxyConfigUpdateFacadeImpl proxyConfigUpdate, List handlers)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field field = ProxyConfigUpdateFacadeImpl.class.getDeclaredField("contextHandlerChain");
+ field.setAccessible(true);
+ field.set(proxyConfigUpdate, handlers);
+ field.get(proxyConfigUpdate);
+ }
+}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateJsonBuilder.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateJsonBuilder.java
index 072ab4a5fd79..eadb476de056 100644
--- a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateJsonBuilder.java
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateJsonBuilder.java
@@ -15,12 +15,30 @@
package com.suse.proxy.test;
+import static com.suse.proxy.ProxyConfigUtils.EMAIL_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.INTERMEDIATE_CAS_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.MAX_CACHE_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PARENT_FQDN_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_CERT_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_KEY_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_PORT_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.REGISTRY_BASE_TAG;
+import static com.suse.proxy.ProxyConfigUtils.REGISTRY_BASE_URL;
+import static com.suse.proxy.ProxyConfigUtils.REGISTRY_MODE;
import static com.suse.proxy.ProxyConfigUtils.REGISTRY_MODE_ADVANCED;
-import static com.suse.proxy.ProxyConfigUtils.REGISTRY_MODE_SIMPLE;
+import static com.suse.proxy.ProxyConfigUtils.ROOT_CA_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.SERVER_ID_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.SOURCE_MODE_FIELD;
import static com.suse.proxy.ProxyConfigUtils.SOURCE_MODE_REGISTRY;
import static com.suse.proxy.ProxyConfigUtils.SOURCE_MODE_RPM;
+import static com.suse.proxy.ProxyConfigUtils.USE_CERTS_MODE_FIELD;
import static com.suse.proxy.ProxyConfigUtils.USE_CERTS_MODE_KEEP;
import static com.suse.proxy.ProxyConfigUtils.USE_CERTS_MODE_REPLACE;
+import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_HTTPD;
+import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_SALT_BROKER;
+import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_SQUID;
+import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_SSH;
+import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_TFTPD;
import static com.suse.utils.Predicates.isProvided;
import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
@@ -85,7 +103,12 @@ public ProxyConfigUpdateJsonBuilder email(String emailIn) {
return this;
}
- public ProxyConfigUpdateJsonBuilder replaceCerts(String rootCAIn, List intermediateCAsIn, String proxyCertIn, String proxyKeyIn) {
+ public ProxyConfigUpdateJsonBuilder replaceCerts(
+ String rootCAIn,
+ List intermediateCAsIn,
+ String proxyCertIn,
+ String proxyKeyIn
+ ) {
useCertsMode = USE_CERTS_MODE_REPLACE;
rootCA = rootCAIn;
intermediateCAs = intermediateCAsIn;
@@ -94,7 +117,12 @@ public ProxyConfigUpdateJsonBuilder replaceCerts(String rootCAIn, List i
return this;
}
- public ProxyConfigUpdateJsonBuilder keepCerts(String rootCAIn, List intermediateCAsIn, String proxyCertIn, String proxyKeyIn) {
+ public ProxyConfigUpdateJsonBuilder keepCerts(
+ String rootCAIn,
+ List intermediateCAsIn,
+ String proxyCertIn,
+ String proxyKeyIn
+ ) {
useCertsMode = USE_CERTS_MODE_KEEP;
rootCA = rootCAIn;
intermediateCAs = intermediateCAsIn;
@@ -128,6 +156,7 @@ public ProxyConfigUpdateJsonBuilder registryBaseTag(String registryBaseTagIn) {
return this;
}
+ @SuppressWarnings("java:S107")
public ProxyConfigUpdateJsonBuilder sourceRegistryAdvanced(
String registryHttpdURLIn, String registryHttpdTagIn,
String registrySaltbrokerURLIn, String registrySaltbrokerTagIn,
@@ -152,36 +181,36 @@ public ProxyConfigUpdateJsonBuilder sourceRegistryAdvanced(
public ProxyConfigUpdateJson build() {
JsonObject requestJsonObject = new JsonObject();
- requestJsonObject.addProperty("serverId", this.serverId);
- requestJsonObject.addProperty("parentFQDN", this.parentFqdn);
- requestJsonObject.addProperty("proxyPort", this.proxyPort);
- requestJsonObject.addProperty("maxSquidCacheSize", this.maxCache);
- requestJsonObject.addProperty("proxyAdminEmail", this.email);
- requestJsonObject.addProperty("useCertsMode", this.useCertsMode);
- requestJsonObject.addProperty("rootCA", this.rootCA);
+ requestJsonObject.addProperty(SERVER_ID_FIELD, this.serverId);
+ requestJsonObject.addProperty(PARENT_FQDN_FIELD, this.parentFqdn);
+ requestJsonObject.addProperty(PROXY_PORT_FIELD, this.proxyPort);
+ requestJsonObject.addProperty(MAX_CACHE_FIELD, this.maxCache);
+ requestJsonObject.addProperty(EMAIL_FIELD, this.email);
+ requestJsonObject.addProperty(USE_CERTS_MODE_FIELD, this.useCertsMode);
+ requestJsonObject.addProperty(ROOT_CA_FIELD, this.rootCA);
JsonArray intermediateCAsArray = new JsonArray();
if (isProvided(this.intermediateCAs)) {
for (String ca : this.intermediateCAs) {
intermediateCAsArray.add(ca);
}
}
- requestJsonObject.add("intermediateCAs", intermediateCAsArray);
- requestJsonObject.addProperty("proxyCertificate", this.proxyCert);
- requestJsonObject.addProperty("proxyKey", this.proxyKey);
- requestJsonObject.addProperty("sourceMode", this.sourceMode);
- requestJsonObject.addProperty("registryMode", this.registryMode);
- requestJsonObject.addProperty("registryBaseURL", this.registryBaseURL);
- requestJsonObject.addProperty("registryBaseTag", this.registryBaseTag);
- requestJsonObject.addProperty("registryHttpdURL", this.registryHttpdURL);
- requestJsonObject.addProperty("registryHttpdTag", this.registryHttpdTag);
- requestJsonObject.addProperty("registrySaltbrokerURL", this.registrySaltbrokerURL);
- requestJsonObject.addProperty("registrySaltbrokerTag", this.registrySaltbrokerTag);
- requestJsonObject.addProperty("registrySquidURL", this.registrySquidURL);
- requestJsonObject.addProperty("registrySquidTag", this.registrySquidTag);
- requestJsonObject.addProperty("registrySshURL", this.registrySshURL);
- requestJsonObject.addProperty("registrySshTag", this.registrySshTag);
- requestJsonObject.addProperty("registryTftpdURL", this.registryTftpdURL);
- requestJsonObject.addProperty("registryTftpdTag", this.registryTftpdTag);
+ requestJsonObject.add(INTERMEDIATE_CAS_FIELD, intermediateCAsArray);
+ requestJsonObject.addProperty(PROXY_CERT_FIELD, this.proxyCert);
+ requestJsonObject.addProperty(PROXY_KEY_FIELD, this.proxyKey);
+ requestJsonObject.addProperty(SOURCE_MODE_FIELD, this.sourceMode);
+ requestJsonObject.addProperty(REGISTRY_MODE, this.registryMode);
+ requestJsonObject.addProperty(REGISTRY_BASE_URL, this.registryBaseURL);
+ requestJsonObject.addProperty(REGISTRY_BASE_TAG, this.registryBaseTag);
+ requestJsonObject.addProperty(PROXY_HTTPD.getUrlField(), this.registryHttpdURL);
+ requestJsonObject.addProperty(PROXY_HTTPD.getTagField(), this.registryHttpdTag);
+ requestJsonObject.addProperty(PROXY_SALT_BROKER.getUrlField(), this.registrySaltbrokerURL);
+ requestJsonObject.addProperty(PROXY_SALT_BROKER.getTagField(), this.registrySaltbrokerTag);
+ requestJsonObject.addProperty(PROXY_SQUID.getUrlField(), this.registrySquidURL);
+ requestJsonObject.addProperty(PROXY_SQUID.getTagField(), this.registrySquidTag);
+ requestJsonObject.addProperty(PROXY_SSH.getUrlField(), this.registrySshURL);
+ requestJsonObject.addProperty(PROXY_SSH.getTagField(), this.registrySshTag);
+ requestJsonObject.addProperty(PROXY_TFTPD.getUrlField(), this.registryTftpdURL);
+ requestJsonObject.addProperty(PROXY_TFTPD.getTagField(), this.registryTftpdTag);
return Json.GSON.fromJson(requestJsonObject, ProxyConfigUpdateJson.class);
}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateRegistryPreConditionsTest.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateRegistryPreConditionsTest.java
index 78c9ac88e5eb..bf691a7a27f8 100644
--- a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateRegistryPreConditionsTest.java
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateRegistryPreConditionsTest.java
@@ -21,7 +21,7 @@
import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_SQUID;
import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_SSH;
import static com.suse.proxy.ProxyContainerImagesEnum.PROXY_TFTPD;
-import static com.suse.proxy.test.ProxyConfigUpdateUtils.assertExpectedErrors;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.assertExpectedErrors;
import static org.junit.jupiter.api.Assertions.assertFalse;
import com.redhat.rhn.testing.MockObjectTestCase;
@@ -42,7 +42,6 @@
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Map;
@@ -51,6 +50,7 @@
* These will assume the previous step in the chain of responsibility {@link ProxyConfigUpdateAcquisitor} and
* {@link ProxyConfigUpdateValidation} have been executed and, no errors have been added to the context.
*/
+@SuppressWarnings({"java:S1171", "java:S3599"})
@ExtendWith(JUnit5Mockery.class)
public class ProxyConfigUpdateRegistryPreConditionsTest extends MockObjectTestCase {
@@ -76,7 +76,8 @@ public void testSuccessWhenSourceModeIsRpm() {
}
/**
- * Test a scenario when sourceMode is set to "Registry" but proxy RegistryUrls failed to be created (on previous steps)
+ * Test a scenario when sourceMode is set to "Registry" but proxy RegistryUrls failed to be created
+ * (on previous steps)
*/
@Test
public void testFailWhenRegistryUrlNotProvided() {
@@ -97,6 +98,7 @@ public void testFailWhenRegistryUrlNotProvided() {
assertExpectedErrors(expectedErrorMessages, proxyConfigUpdateContext);
}
+ @SuppressWarnings("java:S1130") // Suppress the ParseException warning (due to the mocked getTags() method)
@Test
public void testWhenGetTagsThrowsParseException() throws ParseException {
final String[] expectedErrorMessages = {
@@ -137,35 +139,4 @@ public void testWhenGetTagsThrowsParseException() throws ParseException {
assertExpectedErrors(expectedErrorMessages, proxyConfigUpdateContext);
}
- @Test
- public void testSuccess() throws ParseException {
- setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
- ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder().sourceMode(SOURCE_MODE_REGISTRY).build();
- ProxyConfigUpdateContext proxyConfigUpdateContext =
- new ProxyConfigUpdateContext(request, null, null, null);
-
- Map registryUrls = new EnumMap<>(ProxyContainerImagesEnum.class);
- RegistryUrl registryUrl = context.mock(RegistryUrl.class);
- registryUrls.put(PROXY_HTTPD, registryUrl);
- registryUrls.put(PROXY_SALT_BROKER, registryUrl);
- registryUrls.put(PROXY_SQUID, registryUrl);
- registryUrls.put(PROXY_SSH, registryUrl);
- registryUrls.put(PROXY_TFTPD, registryUrl);
- proxyConfigUpdateContext.getRegistryUrls().putAll(registryUrls);
-
- // Inject the mock service so registryUtils.getTags() will not throw an exception
- ProxyRegistryUtils proxyRegistryUtils = context.mock(ProxyRegistryUtils.class);
- ProxyConfigUpdateRegistryPreConditions preConditions =
- new ProxyConfigUpdateRegistryPreConditions(proxyRegistryUtils);
-
- context.checking(new Expectations() {{
- exactly(5).of(proxyRegistryUtils).getTags(with(any(RegistryUrl.class)));
- will(returnValue(new ArrayList<>()));
- }});
-
- preConditions.handle(proxyConfigUpdateContext);
-
- assertFalse(proxyConfigUpdateContext.getErrorReport().hasErrors());
- }
-
}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateTest.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateTest.java
deleted file mode 100644
index 963106a24563..000000000000
--- a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2025 SUSE LLC
- *
- * This software is licensed to you under the GNU General Public License,
- * version 2 (GPLv2). There is NO WARRANTY for this software, express or
- * implied, including the implied warranties of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
- * along with this software; if not, see
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
- */
-
-package com.suse.proxy.test;
-
-import static org.junit.Assert.assertEquals;
-
-import com.redhat.rhn.domain.user.User;
-import com.redhat.rhn.manager.system.SystemManager;
-import com.redhat.rhn.testing.MockObjectTestCase;
-import com.redhat.rhn.testing.RhnBaseTestCase;
-
-import com.suse.manager.webui.services.iface.SaltApi;
-import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
-import com.suse.proxy.update.ProxyConfigUpdate;
-import com.suse.proxy.update.ProxyConfigUpdateContext;
-import com.suse.proxy.update.ProxyConfigUpdateContextHandler;
-
-import org.jmock.Expectations;
-import org.jmock.junit5.JUnit5Mockery;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import java.util.List;
-
-@ExtendWith(JUnit5Mockery.class)
-public class ProxyConfigUpdateTest extends MockObjectTestCase {
-
- private ProxyConfigUpdate proxyConfigUpdate;
- private ProxyConfigUpdateJson request;
- private SystemManager systemManager;
- private SaltApi saltApi;
- private User user;
- private ProxyConfigUpdateContextHandler handler1;
- private ProxyConfigUpdateContextHandler handler2;
-
- @Before
- public void setUp() {
- request = new ProxyConfigUpdateJson();
- systemManager = context.mock(SystemManager.class);
- saltApi = context.mock(SaltApi.class);
- user = context.mock(User.class);
- handler1 = context.mock(ProxyConfigUpdateContextHandler.class, "handler1");
- handler2 = context.mock(ProxyConfigUpdateContextHandler.class, "handler2");
-
- proxyConfigUpdate = null; // new ProxyConfigUpdate(List.of(handler1, handler2));
- }
-
- @Test
- public void testUpdate() {
- context.checking(new Expectations() {{
- oneOf(handler1).handle(with(any(ProxyConfigUpdateContext.class)));
- oneOf(handler2).handle(with(any(ProxyConfigUpdateContext.class)));
- }});
-
- proxyConfigUpdate.update(request, systemManager, saltApi, user);
- }
-
- @Test
- public void testUpdateWithError() {
- context.checking(new Expectations() {{
- oneOf(handler1).handle(with(any(ProxyConfigUpdateContext.class)));
- will(throwException(new RuntimeException("Handler error")));
- }});
-
- try {
- proxyConfigUpdate.update(request, systemManager, saltApi, user);
- } catch (RuntimeException e) {
- assertEquals("Handler error", e.getMessage());
- }
-
- context.assertIsSatisfied();
- }
-}
\ No newline at end of file
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateTestUtils.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateTestUtils.java
new file mode 100644
index 000000000000..f05b4dbc9a45
--- /dev/null
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateTestUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.test;
+
+import static com.redhat.rhn.common.ExceptionMessage.NOT_INSTANTIABLE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.redhat.rhn.common.RhnError;
+
+import com.suse.proxy.ProxyContainerImagesEnum;
+import com.suse.proxy.update.ProxyConfigUpdateContext;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Utils for ProxyConfigUpdate tests
+ */
+public class ProxyConfigUpdateTestUtils {
+
+ public static final String DUMMY_PROXY_FQDN = "proxy.fqdn.com";
+ public static final String DUMMY_PARENT_FQDN = "parent.fqdn.com";
+ public static final String DUMMY_ROOT_CA = "rootCA";
+ public static final String DUMMY_INTERMEDIATE_CA_1 = "intermediateCA1";
+ public static final String DUMMY_INTERMEDIATE_CA_2 = "intermediateCA2";
+ public static final String DUMMY_PROXY_CERT = "proxyCert";
+ public static final String DUMMY_PROXY_KEY = "proxyKey";
+ public static final String DUMMY_TAG = "tag";
+ public static final String DUMMY_ADMIN_MAIL = "admin@suse.com";
+ public static final String DUMMY_URL_PREFIX = "http://suse.com/images/";
+
+ public static final long DUMMY_SERVER_ID = 123L;
+ public static final int DUMMY_PROXY_PORT = 8080;
+ public static final int DUMMY_MAX_CACHE = 1024;
+
+ private ProxyConfigUpdateTestUtils() {
+ throw new UnsupportedOperationException(NOT_INSTANTIABLE);
+ }
+
+ /**
+ * Asserts the expected error messages are present in the context
+ *
+ * @param expectedErrorMessages the expected error messages array string
+ * @param context the context
+ */
+ public static void assertExpectedErrors(String[] expectedErrorMessages, ProxyConfigUpdateContext context) {
+ assertTrue(context.getErrorReport().hasErrors());
+ assertEquals(expectedErrorMessages.length, context.getErrorReport().getErrors().size());
+
+ Set actualErrorMessages =
+ context.getErrorReport().getErrors().stream().map(RhnError::getMessage).collect(Collectors.toSet());
+ assertTrue(actualErrorMessages.containsAll(Set.of(expectedErrorMessages)));
+ }
+
+ /**
+ * Generates well-formed dummy URL for the given image.
+ * @param proxyContainerImagesEnum the image
+ * @return the dummy URL
+ */
+ public static String getDummyUrl(ProxyContainerImagesEnum proxyContainerImagesEnum) {
+ return DUMMY_URL_PREFIX + proxyContainerImagesEnum.getImageName();
+ }
+
+ /**
+ * Generates a dynamic dummy tag for the given image.
+ * @param proxyContainerImagesEnum the image
+ * @return the dummy tag
+ */
+ public static String getDummyTag(ProxyContainerImagesEnum proxyContainerImagesEnum) {
+ return DUMMY_TAG + "_" + proxyContainerImagesEnum.getImageName();
+ }
+
+}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateUtils.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateUtils.java
deleted file mode 100644
index 9b23afb0b6df..000000000000
--- a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateUtils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2025 SUSE LLC
- *
- * This software is licensed to you under the GNU General Public License,
- * version 2 (GPLv2). There is NO WARRANTY for this software, express or
- * implied, including the implied warranties of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
- * along with this software; if not, see
- * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * Red Hat trademarks are not licensed under GPLv2. No permission is
- * granted to use or replicate Red Hat trademarks that are incorporated
- * in this software or its documentation.
- */
-
-package com.suse.proxy.test;
-
-import static com.redhat.rhn.common.ExceptionMessage.NOT_INSTANTIABLE;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import com.redhat.rhn.common.RhnError;
-
-import com.suse.proxy.update.ProxyConfigUpdateContext;
-
-import java.util.List;
-
-public class ProxyConfigUpdateUtils {
-
- private ProxyConfigUpdateUtils() {
- throw new UnsupportedOperationException(NOT_INSTANTIABLE);
- }
-
- /**
- * Asserts the expected error messages are present in the context
- *
- * @param expectedErrorMessages the expected error messages array string
- * @param context the context
- */
- public static void assertExpectedErrors(String[] expectedErrorMessages, ProxyConfigUpdateContext context) {
- assertTrue(context.getErrorReport().hasErrors());
- assertEquals(expectedErrorMessages.length, context.getErrorReport().getErrors().size());
-
- List actualErrorMessages =
- context.getErrorReport().getErrors().stream().map(RhnError::getMessage).toList();
- assertTrue(actualErrorMessages.containsAll(List.of(expectedErrorMessages)));
- }
-
-}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateValidationTest.java b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateValidationTest.java
index f9cbd6325ad2..3a9cba869189 100644
--- a/java/code/src/com/suse/proxy/test/ProxyConfigUpdateValidationTest.java
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUpdateValidationTest.java
@@ -18,7 +18,17 @@
import static com.suse.proxy.ProxyConfigUtils.REGISTRY_MODE_ADVANCED;
import static com.suse.proxy.ProxyConfigUtils.REGISTRY_MODE_SIMPLE;
import static com.suse.proxy.ProxyConfigUtils.SOURCE_MODE_REGISTRY;
-import static com.suse.proxy.test.ProxyConfigUpdateUtils.assertExpectedErrors;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_ADMIN_MAIL;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_MAX_CACHE;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PARENT_FQDN;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_CERT;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_FQDN;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_KEY;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_PORT;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_ROOT_CA;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_SERVER_ID;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_TAG;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.assertExpectedErrors;
import static org.junit.jupiter.api.Assertions.assertFalse;
import com.redhat.rhn.domain.server.Server;
@@ -43,6 +53,8 @@
@ExtendWith(JUnit5Mockery.class)
public class ProxyConfigUpdateValidationTest extends MockObjectTestCase {
+ public static final String UNKNOWN = "unknown";
+
/**
* Test a scenario where ProxyConfigUpdateJson is resolved as being empty
*/
@@ -84,19 +96,19 @@ public void testFailureWhenProxyFqdnNotResolvedAndParentFqdnIsInvalid() {
};
ProxyConfigUpdateJson request = new ProxyConfigUpdateJsonBuilder()
- .serverId(123L)
+ .serverId(DUMMY_SERVER_ID)
.parentFqdn("invalid@fqdn")
- .proxyPort(3182)
- .maxCache(1000)
- .email("admin@suse.com")
+ .proxyPort(DUMMY_PROXY_PORT)
+ .maxCache(DUMMY_MAX_CACHE)
+ .email(DUMMY_ADMIN_MAIL)
.sourceRPM()
.build();
ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
// certificate content is handled in {@link ProxyConfigUpdateAcquisitor} and set directly in the context
- proxyConfigUpdateContext.setRootCA("rootCA");
- proxyConfigUpdateContext.setProxyCert("proxyCert");
- proxyConfigUpdateContext.setProxyKey("proxyKey");
+ proxyConfigUpdateContext.setRootCA(DUMMY_ROOT_CA);
+ proxyConfigUpdateContext.setProxyCert(DUMMY_PROXY_CERT);
+ proxyConfigUpdateContext.setProxyKey(DUMMY_PROXY_KEY);
//
new ProxyConfigUpdateValidation().handle(proxyConfigUpdateContext);
@@ -114,11 +126,11 @@ public void testSuccessWhenReplaceCerts() {
ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
// certificate content is handled in {@link ProxyConfigUpdateAcquisitor} and set directly in the context
- proxyConfigUpdateContext.setRootCA("rootCA");
- proxyConfigUpdateContext.setProxyCert("proxyCert");
- proxyConfigUpdateContext.setProxyKey("proxyKey");
- proxyConfigUpdateContext.setParentServer(new Server(123L, "parent.fqdn.com"));
- proxyConfigUpdateContext.setProxyFqdn("proxy.fqdn.com");
+ proxyConfigUpdateContext.setRootCA(DUMMY_ROOT_CA);
+ proxyConfigUpdateContext.setProxyCert(DUMMY_PROXY_CERT);
+ proxyConfigUpdateContext.setProxyKey(DUMMY_PROXY_KEY);
+ proxyConfigUpdateContext.setParentServer(new Server(DUMMY_SERVER_ID, DUMMY_PARENT_FQDN));
+ proxyConfigUpdateContext.setProxyFqdn(DUMMY_PROXY_FQDN);
//
new ProxyConfigUpdateValidation().handle(proxyConfigUpdateContext);
@@ -156,8 +168,8 @@ public void testFailWhenKeepCertsButNoExistingProxyConfig() {
.build();
ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
- proxyConfigUpdateContext.setParentServer(new Server(123L, "parent.fqdn.com"));
- proxyConfigUpdateContext.setProxyFqdn("proxy.fqdn.com");
+ proxyConfigUpdateContext.setParentServer(new Server(DUMMY_SERVER_ID, DUMMY_PARENT_FQDN));
+ proxyConfigUpdateContext.setProxyFqdn(DUMMY_PROXY_FQDN);
//
new ProxyConfigUpdateValidation().handle(proxyConfigUpdateContext);
@@ -181,8 +193,8 @@ public void testFailWhenKeepCertsButNoExistingCertificates() {
.build();
ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
- proxyConfigUpdateContext.setParentServer(new Server(123L, "parent.fqdn.com"));
- proxyConfigUpdateContext.setProxyFqdn("proxy.fqdn.com");
+ proxyConfigUpdateContext.setParentServer(new Server(DUMMY_SERVER_ID, DUMMY_PARENT_FQDN));
+ proxyConfigUpdateContext.setProxyFqdn(DUMMY_PROXY_FQDN);
proxyConfigUpdateContext.setProxyConfig(new ProxyConfig());
//
@@ -202,7 +214,7 @@ public void testFailWhenInvalidSourceMode() {
};
ProxyConfigUpdateJson request = getBaseRequestWithReplaceCerts()
- .sourceMode("unknown")
+ .sourceMode(UNKNOWN)
.build();
ProxyConfigUpdateContext proxyConfigUpdateContext = getProxyConfigUpdateContext(request);
@@ -225,7 +237,7 @@ public void testFailWhenInvalidRegistryMode() {
ProxyConfigUpdateJson request = getBaseRequestWithReplaceCerts()
.sourceMode(SOURCE_MODE_REGISTRY)
- .registryMode("unknown")
+ .registryMode(UNKNOWN)
.build();
ProxyConfigUpdateContext proxyConfigUpdateContext = getProxyConfigUpdateContext(request);
@@ -267,7 +279,7 @@ public void testSuccessWhenSimpleRegistryMode() {
.sourceMode(SOURCE_MODE_REGISTRY)
.registryMode(REGISTRY_MODE_SIMPLE)
.registryBaseURL("http://registry.suse.com")
- .registryBaseTag("latest")
+ .registryBaseTag(DUMMY_TAG)
.build();
ProxyConfigUpdateContext proxyConfigUpdateContext = getProxyConfigUpdateContext(request);
@@ -315,11 +327,11 @@ public void testFailWhenAdvancedRegistryModeButNoUrlsOrTagsProvided() {
public void testSuccessWhenAdvancedRegistryMode() {
ProxyConfigUpdateJson request = getBaseRequestWithReplaceCerts()
.sourceRegistryAdvanced(
- "http://registry.suse.com/httpd", "latest",
- "http://registry.suse.com/saltbroker", "latest",
- "http://registry.suse.com/squid", "latest",
- "http://registry.suse.com/ssh", "latest",
- "http://registry.suse.com/tftpd", "latest"
+ "http://registry.suse.com/httpd", DUMMY_TAG,
+ "http://registry.suse.com/saltbroker", DUMMY_TAG,
+ "http://registry.suse.com/squid", DUMMY_TAG,
+ "http://registry.suse.com/ssh", DUMMY_TAG,
+ "http://registry.suse.com/tftpd", DUMMY_TAG
)
.build();
@@ -340,13 +352,13 @@ public void testSuccessWhenAdvancedRegistryMode() {
*/
private static ProxyConfigUpdateContext getProxyConfigUpdateContext(ProxyConfigUpdateJson request) {
ProxyConfigUpdateContext proxyConfigUpdateContext = new ProxyConfigUpdateContext(request, null, null, null);
- proxyConfigUpdateContext.setParentServer(new Server(123L, "parent.fqdn.com"));
- proxyConfigUpdateContext.setProxyFqdn("proxy.fqdn.com");
+ proxyConfigUpdateContext.setParentServer(new Server(DUMMY_SERVER_ID, DUMMY_PARENT_FQDN));
+ proxyConfigUpdateContext.setProxyFqdn(DUMMY_PROXY_FQDN);
// certificate content is handled in {@link ProxyConfigUpdateAcquisitor} and set directly in the context
proxyConfigUpdateContext.setProxyConfig(new ProxyConfig());
- proxyConfigUpdateContext.setRootCA("rootCA");
- proxyConfigUpdateContext.setProxyCert("proxyCert");
- proxyConfigUpdateContext.setProxyKey("proxyKey");
+ proxyConfigUpdateContext.setRootCA(DUMMY_ROOT_CA);
+ proxyConfigUpdateContext.setProxyCert(DUMMY_PROXY_CERT);
+ proxyConfigUpdateContext.setProxyKey(DUMMY_PROXY_KEY);
return proxyConfigUpdateContext;
}
@@ -357,11 +369,11 @@ private static ProxyConfigUpdateContext getProxyConfigUpdateContext(ProxyConfigU
*/
private ProxyConfigUpdateJsonBuilder getBaseRequestWithRpm() {
return new ProxyConfigUpdateJsonBuilder()
- .serverId(123L)
- .parentFqdn("proxy.suse.com")
- .proxyPort(3182)
- .maxCache(1000)
- .email("admin@suse.com")
+ .serverId(DUMMY_SERVER_ID)
+ .parentFqdn(DUMMY_PARENT_FQDN)
+ .proxyPort(DUMMY_PROXY_PORT)
+ .maxCache(DUMMY_MAX_CACHE)
+ .email(DUMMY_ADMIN_MAIL)
.sourceRPM();
}
@@ -372,11 +384,11 @@ private ProxyConfigUpdateJsonBuilder getBaseRequestWithRpm() {
*/
private ProxyConfigUpdateJsonBuilder getBaseRequestWithReplaceCerts() {
return new ProxyConfigUpdateJsonBuilder()
- .serverId(123L)
- .parentFqdn("proxy.suse.com")
- .proxyPort(3182)
- .maxCache(1000)
- .email("admin@suse.com")
+ .serverId(DUMMY_SERVER_ID)
+ .parentFqdn(DUMMY_PARENT_FQDN)
+ .proxyPort(DUMMY_PROXY_PORT)
+ .maxCache(DUMMY_MAX_CACHE)
+ .email(DUMMY_ADMIN_MAIL)
.replaceCerts(null, null, null, null);
}
}
diff --git a/java/code/src/com/suse/proxy/test/ProxyConfigUtilsTest.java b/java/code/src/com/suse/proxy/test/ProxyConfigUtilsTest.java
new file mode 100644
index 000000000000..448ba673ccb5
--- /dev/null
+++ b/java/code/src/com/suse/proxy/test/ProxyConfigUtilsTest.java
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.test;
+
+import static com.suse.proxy.ProxyConfigUtils.EMAIL_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.INTERMEDIATE_CAS_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.MAX_CACHE_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PARENT_FQDN_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PILLAR_REGISTRY_ENTRY;
+import static com.suse.proxy.ProxyConfigUtils.PILLAR_REGISTRY_TAG_ENTRY;
+import static com.suse.proxy.ProxyConfigUtils.PILLAR_REGISTRY_URL_ENTRY;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_CERT_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_FQDN_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_KEY_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.PROXY_PORT_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.ROOT_CA_FIELD;
+import static com.suse.proxy.ProxyConfigUtils.SERVER_ID_FIELD;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_ADMIN_MAIL;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_INTERMEDIATE_CA_1;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_INTERMEDIATE_CA_2;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_MAX_CACHE;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PARENT_FQDN;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_CERT;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_FQDN;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_KEY;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_PROXY_PORT;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_ROOT_CA;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_SERVER_ID;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_TAG;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.DUMMY_URL_PREFIX;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.getDummyTag;
+import static com.suse.proxy.test.ProxyConfigUpdateTestUtils.getDummyUrl;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.redhat.rhn.domain.server.Pillar;
+import com.redhat.rhn.testing.MockObjectTestCase;
+
+import com.suse.proxy.ProxyConfigUtils;
+import com.suse.proxy.ProxyContainerImagesEnum;
+import com.suse.proxy.model.ProxyConfig;
+import com.suse.proxy.model.ProxyConfigImage;
+
+import org.jmock.Expectations;
+import org.jmock.imposters.ByteBuddyClassImposteriser;
+import org.jmock.junit5.JUnit5Mockery;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Test class for {@link ProxyConfigUtils}
+ */
+@SuppressWarnings({"squid:S3599", "java:S1171"}) //jmock
+@ExtendWith(JUnit5Mockery.class)
+public class ProxyConfigUtilsTest extends MockObjectTestCase {
+ public static final String DUMMY_TAG_2 = "anotherTag";
+
+ private Pillar mockPillar;
+
+ @BeforeEach
+ public void setUp() {
+ setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
+ mockPillar = context.mock(Pillar.class);
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#proxyConfigFromPillar(Pillar)} method when the pillar returns null.
+ **/
+ @Test
+ public void testProxyConfigWhenNoPillar() {
+ context.checking(new Expectations() {{
+ oneOf(mockPillar).getPillar();
+ will(returnValue(null));
+ }});
+
+ ProxyConfig proxyConfig = ProxyConfigUtils.proxyConfigFromPillar(mockPillar);
+
+ assertNull(proxyConfig.getServerId());
+ assertNull(proxyConfig.getProxyFqdn());
+ assertNull(proxyConfig.getParentFqdn());
+ assertNull(proxyConfig.getProxyPort());
+ assertNull(proxyConfig.getMaxCache());
+ assertNull(proxyConfig.getEmail());
+ assertNull(proxyConfig.getRootCA());
+ assertNull(proxyConfig.getProxyCert());
+ assertNull(proxyConfig.getProxyKey());
+ assertNull(proxyConfig.getIntermediateCAs());
+ assertNull(proxyConfig.getHttpdImage());
+ assertNull(proxyConfig.getSaltBrokerImage());
+ assertNull(proxyConfig.getSquidImage());
+ assertNull(proxyConfig.getSshImage());
+ assertNull(proxyConfig.getTftpdImage());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#proxyConfigFromPillar(Pillar)} method when the pillar is returns no data.
+ */
+ @Test
+ public void testProxyConfigWhenBlankPillar() {
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(new HashMap<>()));
+ }});
+
+ ProxyConfig proxyConfig = ProxyConfigUtils.proxyConfigFromPillar(mockPillar);
+
+ assertNull(proxyConfig.getServerId());
+ assertNull(proxyConfig.getProxyFqdn());
+ assertNull(proxyConfig.getParentFqdn());
+ assertNull(proxyConfig.getProxyPort());
+ assertNull(proxyConfig.getMaxCache());
+ assertNull(proxyConfig.getEmail());
+ assertNull(proxyConfig.getRootCA());
+ assertNull(proxyConfig.getProxyCert());
+ assertNull(proxyConfig.getProxyKey());
+ assertNull(proxyConfig.getIntermediateCAs());
+ assertNull(proxyConfig.getHttpdImage());
+ assertNull(proxyConfig.getSaltBrokerImage());
+ assertNull(proxyConfig.getSquidImage());
+ assertNull(proxyConfig.getSshImage());
+ assertNull(proxyConfig.getTftpdImage());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#proxyConfigFromPillar(Pillar)} method when the pillar returns full data
+ * with registries.
+ */
+ @Test
+ public void testProxyConfigFromPillarWithRegistries() {
+ final String expectedHttpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ final String expectedHttpdTag = getDummyTag(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdTag = getDummyTag(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(createPillarMapWithRegistryAdvancedMode()));
+ }});
+
+ //
+ ProxyConfig proxyConfig = ProxyConfigUtils.proxyConfigFromPillar(mockPillar);
+
+ assertEquals(DUMMY_SERVER_ID, proxyConfig.getServerId());
+ assertEquals(DUMMY_PROXY_FQDN, proxyConfig.getProxyFqdn());
+ assertEquals(DUMMY_PARENT_FQDN, proxyConfig.getParentFqdn());
+ assertEquals(DUMMY_PROXY_PORT, proxyConfig.getProxyPort());
+ assertEquals(DUMMY_MAX_CACHE, proxyConfig.getMaxCache());
+ assertEquals(DUMMY_ADMIN_MAIL, proxyConfig.getEmail());
+ assertEquals(DUMMY_ROOT_CA, proxyConfig.getRootCA());
+ assertEquals(DUMMY_PROXY_CERT, proxyConfig.getProxyCert());
+ assertEquals(DUMMY_PROXY_KEY, proxyConfig.getProxyKey());
+ assertTrue(proxyConfig.getIntermediateCAs().contains(DUMMY_INTERMEDIATE_CA_1));
+ assertTrue(proxyConfig.getIntermediateCAs().contains(DUMMY_INTERMEDIATE_CA_2));
+
+ ProxyConfigImage httpdImage = proxyConfig.getHttpdImage();
+ assertNotNull(httpdImage);
+ assertEquals(expectedHttpdUrl, httpdImage.getUrl());
+ assertEquals(expectedHttpdTag, httpdImage.getTag());
+
+ ProxyConfigImage saltBrokerImage = proxyConfig.getSaltBrokerImage();
+ assertNotNull(saltBrokerImage);
+ assertEquals(expectedSaltBrokerUrl, saltBrokerImage.getUrl());
+ assertEquals(expectedSaltBrokerTag, saltBrokerImage.getTag());
+
+ ProxyConfigImage squidImage = proxyConfig.getSquidImage();
+ assertNotNull(squidImage);
+ assertEquals(expectedSquidUrl, squidImage.getUrl());
+ assertEquals(expectedSquidTag, squidImage.getTag());
+
+ ProxyConfigImage sshImage = proxyConfig.getSshImage();
+ assertNotNull(sshImage);
+ assertEquals(expectedSshUrl, sshImage.getUrl());
+ assertEquals(expectedSshTag, sshImage.getTag());
+
+ ProxyConfigImage tftpdImage = proxyConfig.getTftpdImage();
+ assertNotNull(tftpdImage);
+ assertEquals(expectedTftpdUrl, tftpdImage.getUrl());
+ assertEquals(expectedTftpdTag, tftpdImage.getTag());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#getCommonTag} method when the images have a common tag.
+ */
+ @Test
+ public void testGetCommonTagWhenCommonTag() {
+ ProxyConfigImage image1 = new ProxyConfigImage(DUMMY_URL_PREFIX, DUMMY_TAG);
+ ProxyConfigImage image2 = new ProxyConfigImage(DUMMY_URL_PREFIX, DUMMY_TAG);
+
+ Optional commonTag = ProxyConfigUtils.getCommonTag(image1, image2);
+
+ assertTrue(commonTag.isPresent());
+ assertEquals(DUMMY_TAG, commonTag.get());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#getCommonTag} method when the images have no common tag.
+ */
+ @Test
+ public void testGetCommonTagWhenNoCommonTag() {
+ ProxyConfigImage image1 = new ProxyConfigImage(DUMMY_URL_PREFIX, DUMMY_TAG);
+ ProxyConfigImage image2 = new ProxyConfigImage(DUMMY_URL_PREFIX, DUMMY_TAG_2);
+
+ Optional commonTag = ProxyConfigUtils.getCommonTag(image1, image2);
+
+ assertFalse(commonTag.isPresent());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#getCommonPrefix} method when the images have a common prefix.
+ */
+ @Test
+ public void testGetCommonPrefixWhenCommonPrefixAndImageNamesMatch() {
+ ProxyConfigImage httpdImage =
+ new ProxyConfigImage(getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD), DUMMY_TAG);
+ ProxyConfigImage squidImage =
+ new ProxyConfigImage(getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID), DUMMY_TAG_2);
+
+ Optional commonPrefix = ProxyConfigUtils.getCommonPrefix(httpdImage, squidImage);
+
+ assertTrue(commonPrefix.isPresent());
+ assertEquals(DUMMY_URL_PREFIX, commonPrefix.get());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#getCommonPrefix} method when the images have no common prefix.
+ */
+ @Test
+ public void testGetCommonPrefixWhenNoCommonPrefixAndImageNamesMatch() {
+ ProxyConfigImage httpdImage = new ProxyConfigImage(
+ "http://not.suse.com/images/" + ProxyContainerImagesEnum.PROXY_HTTPD.getImageName(), DUMMY_TAG
+ );
+ ProxyConfigImage squidImage =
+ new ProxyConfigImage(getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID), DUMMY_TAG_2);
+
+ Optional commonPrefix = ProxyConfigUtils.getCommonPrefix(httpdImage, squidImage);
+
+ assertFalse(commonPrefix.isPresent());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#getCommonPrefix} method when the images have a common prefix but the images
+ * names do not match the expected ones at {@link ProxyContainerImagesEnum}.
+ */
+ @Test
+ public void testGetCommonPrefixWhenCommonPrefixAndImageNamesDoNotMatch() {
+ ProxyConfigImage image =
+ new ProxyConfigImage(DUMMY_URL_PREFIX + "not-fitting-image-name", DUMMY_TAG);
+ ProxyConfigImage squidImage =
+ new ProxyConfigImage(getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID), DUMMY_TAG);
+
+ Optional commonPrefix = ProxyConfigUtils.getCommonPrefix(image, squidImage);
+
+ assertFalse(commonPrefix.isPresent());
+ }
+
+ @Test
+ public void testGetCommonPrefixWhenInvalidScenarios() {
+ ProxyConfigImage nullImage = null;
+ ProxyConfigImage emptyImage = new ProxyConfigImage();
+ ProxyConfigImage emptyUrlAndTagImage = new ProxyConfigImage("", "");
+ ProxyConfigImage emptyUrlImage = new ProxyConfigImage("", DUMMY_TAG);
+ ProxyConfigImage noImageUrlImage =
+ new ProxyConfigImage("https://suse.com", "");
+ ProxyConfigImage invalidUrlImage = new ProxyConfigImage("something@not.valid", DUMMY_TAG);
+
+ Optional nullImageCommonPrefix = ProxyConfigUtils.getCommonPrefix(nullImage);
+ Optional emptyImageCommonPrefix = ProxyConfigUtils.getCommonPrefix(emptyImage);
+ Optional emptyUrlAndTagImageCommonPrefix = ProxyConfigUtils.getCommonPrefix(emptyUrlAndTagImage);
+ Optional emptyUrlImageCommonPrefix = ProxyConfigUtils.getCommonPrefix(emptyUrlImage);
+ Optional noImageUrlImageCommonPrefix = ProxyConfigUtils.getCommonPrefix(noImageUrlImage);
+ Optional invalidUrlImageCommonPrefix = ProxyConfigUtils.getCommonPrefix(invalidUrlImage);
+
+ assertFalse(nullImageCommonPrefix.isPresent());
+ assertFalse(emptyImageCommonPrefix.isPresent());
+ assertFalse(emptyUrlAndTagImageCommonPrefix.isPresent());
+ assertFalse(emptyUrlImageCommonPrefix.isPresent());
+ assertFalse(noImageUrlImageCommonPrefix.isPresent());
+ assertFalse(invalidUrlImageCommonPrefix.isPresent());
+ }
+
+
+ /**
+ * Tests the {@link ProxyConfigUtils#dataMapFromProxyConfig} method when the proxy config is empty.
+ */
+ @Test
+ public void testDataMapFromProxyConfigWhenEmpty() {
+ Map dataMap = ProxyConfigUtils.dataMapFromProxyConfig(new ProxyConfig());
+
+ assertNull(dataMap.get(ProxyConfigUtils.SERVER_ID_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.PROXY_FQDN_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#dataMapFromProxyConfig} method when the proxy config is null.
+ */
+ @Test
+ public void testDataMapFromProxyConfigWhenNull() {
+ Map dataMap = ProxyConfigUtils.dataMapFromProxyConfig(null);
+
+ assertNull(dataMap.get(ProxyConfigUtils.SERVER_ID_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.PROXY_FQDN_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getTagField()));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#dataMapFromProxyConfig} method in a scenario of using RPM as the source mode.
+ */
+ @Test
+ public void testDataMapFromProxyConfigWhenRpm() {
+ ProxyConfig proxyConfig = new ProxyConfig();
+
+ proxyConfig.setServerId(DUMMY_SERVER_ID);
+ proxyConfig.setProxyFqdn(DUMMY_PROXY_FQDN);
+ proxyConfig.setParentFqdn(DUMMY_PARENT_FQDN);
+ proxyConfig.setProxyPort(DUMMY_PROXY_PORT);
+ proxyConfig.setMaxCache(DUMMY_MAX_CACHE);
+ proxyConfig.setEmail(DUMMY_ADMIN_MAIL);
+
+ //
+ Map dataMap = ProxyConfigUtils.dataMapFromProxyConfig(proxyConfig);
+
+ //
+ assertEquals(DUMMY_SERVER_ID, dataMap.get(ProxyConfigUtils.SERVER_ID_FIELD));
+ assertEquals(DUMMY_PROXY_FQDN, dataMap.get(ProxyConfigUtils.PROXY_FQDN_FIELD));
+ assertEquals(DUMMY_PARENT_FQDN, dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertEquals(DUMMY_PROXY_PORT, dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertEquals(DUMMY_MAX_CACHE, dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertEquals(DUMMY_ADMIN_MAIL, dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+
+ assertEquals(ProxyConfigUtils.SOURCE_MODE_RPM, dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getTagField()));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#dataMapFromProxyConfig} method in a scenario of using the registry in
+ * in simple mode.
+ */
+ @Test
+ public void testDataMapFromProxyConfigWhenRegistrySimpleMode() {
+ final String expectedHttpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ //
+ ProxyConfig proxyConfig = new ProxyConfig();
+
+ proxyConfig.setServerId(DUMMY_SERVER_ID);
+ proxyConfig.setProxyFqdn(DUMMY_PROXY_FQDN);
+ proxyConfig.setParentFqdn(DUMMY_PARENT_FQDN);
+ proxyConfig.setProxyPort(DUMMY_PROXY_PORT);
+ proxyConfig.setMaxCache(DUMMY_MAX_CACHE);
+ proxyConfig.setEmail(DUMMY_ADMIN_MAIL);
+ proxyConfig.setHttpdImage(new ProxyConfigImage(expectedHttpdUrl, DUMMY_TAG));
+ proxyConfig.setSaltBrokerImage(new ProxyConfigImage(expectedSaltBrokerUrl, DUMMY_TAG));
+ proxyConfig.setSquidImage(new ProxyConfigImage(expectedSquidUrl, DUMMY_TAG));
+ proxyConfig.setSshImage(new ProxyConfigImage(expectedSshUrl, DUMMY_TAG));
+ proxyConfig.setTftpdImage(new ProxyConfigImage(expectedTftpdUrl, DUMMY_TAG));
+
+ //
+ Map dataMap = ProxyConfigUtils.dataMapFromProxyConfig(proxyConfig);
+
+ //
+ assertEquals(DUMMY_SERVER_ID, dataMap.get(ProxyConfigUtils.SERVER_ID_FIELD));
+ assertEquals(DUMMY_PROXY_FQDN, dataMap.get(ProxyConfigUtils.PROXY_FQDN_FIELD));
+ assertEquals(DUMMY_PARENT_FQDN, dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertEquals(DUMMY_PROXY_PORT, dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertEquals(DUMMY_MAX_CACHE, dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertEquals(DUMMY_ADMIN_MAIL, dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+
+ assertEquals(ProxyConfigUtils.SOURCE_MODE_REGISTRY, dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+ assertEquals(ProxyConfigUtils.REGISTRY_MODE_SIMPLE, dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+ assertEquals(DUMMY_URL_PREFIX, dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertEquals(DUMMY_TAG, dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getTagField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getUrlField()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getTagField()));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#dataMapFromProxyConfig} method in a scenario of using the registry in
+ * advanced mode.
+ */
+ @Test
+ public void testDataMapFromProxyConfigWhenRegistryAdvancedMode() {
+ final String expectedHttpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ final String expectedHttpdTag = getDummyTag(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdTag = getDummyTag(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ //
+ ProxyConfig proxyConfig = new ProxyConfig();
+
+ proxyConfig.setServerId(DUMMY_SERVER_ID);
+ proxyConfig.setProxyFqdn(DUMMY_PROXY_FQDN);
+ proxyConfig.setParentFqdn(DUMMY_PARENT_FQDN);
+ proxyConfig.setProxyPort(DUMMY_PROXY_PORT);
+ proxyConfig.setMaxCache(DUMMY_MAX_CACHE);
+ proxyConfig.setEmail(DUMMY_ADMIN_MAIL);
+ proxyConfig.setHttpdImage(new ProxyConfigImage(expectedHttpdUrl, expectedHttpdTag));
+ proxyConfig.setSaltBrokerImage(new ProxyConfigImage(expectedSaltBrokerUrl, expectedSaltBrokerTag));
+ proxyConfig.setSquidImage(new ProxyConfigImage(expectedSquidUrl, expectedSquidTag));
+ proxyConfig.setSshImage(new ProxyConfigImage(expectedSshUrl, expectedSshTag));
+ proxyConfig.setTftpdImage(new ProxyConfigImage(expectedTftpdUrl, expectedTftpdTag));
+
+ //
+ Map dataMap = ProxyConfigUtils.dataMapFromProxyConfig(proxyConfig);
+
+ //
+ assertEquals(DUMMY_SERVER_ID, dataMap.get(ProxyConfigUtils.SERVER_ID_FIELD));
+ assertEquals(DUMMY_PROXY_FQDN, dataMap.get(ProxyConfigUtils.PROXY_FQDN_FIELD));
+ assertEquals(DUMMY_PARENT_FQDN, dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertEquals(DUMMY_PROXY_PORT, dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertEquals(DUMMY_MAX_CACHE, dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertEquals(DUMMY_ADMIN_MAIL, dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+
+ assertEquals(ProxyConfigUtils.SOURCE_MODE_REGISTRY, dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+ assertEquals(ProxyConfigUtils.REGISTRY_MODE_ADVANCED, dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+
+ assertEquals(expectedHttpdUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getUrlField()));
+ assertEquals(expectedHttpdTag, dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getTagField()));
+ assertEquals(expectedSaltBrokerUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getUrlField()));
+ assertEquals(expectedSaltBrokerTag, dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getTagField()));
+ assertEquals(expectedSquidUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getUrlField()));
+ assertEquals(expectedSquidTag, dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getTagField()));
+ assertEquals(expectedSshUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getUrlField()));
+ assertEquals(expectedSshTag, dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getTagField()));
+ assertEquals(expectedTftpdUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getUrlField()));
+ assertEquals(expectedTftpdTag, dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getTagField()));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#applyProxyConfigDataFromPillar(Pillar)} method when the pillar returns null.
+ */
+ @Test
+ public void testApplyProxyConfigDataFromPillarWhenNoPillar() {
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(null));
+ }});
+
+ Map dataMap = ProxyConfigUtils.applyProxyConfigDataFromPillar(mockPillar);
+
+ assertNotNull(dataMap);
+ assertTrue(dataMap.isEmpty());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#applyProxyConfigDataFromPillar(Pillar)} method when the pillar returns empty
+ */
+ @Test
+ public void testApplyProxyConfigDataFromPillarWhenEmptyPillar() {
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(new HashMap<>()));
+ }});
+
+ Map dataMap = ProxyConfigUtils.applyProxyConfigDataFromPillar(mockPillar);
+
+ assertNotNull(dataMap);
+ assertTrue(dataMap.isEmpty());
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#applyProxyConfigDataFromPillar(Pillar)} method when the pillar returns
+ * full data in scope of registry advanced mode.
+ */
+ @Test
+ public void testApplyProxyConfigDataFromPillarWhenRegistryAdvancedMode() {
+ final String expectedHttpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ final String expectedHttpdTag = getDummyTag(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshTag = getDummyTag(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdTag = getDummyTag(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(createPillarMapWithRegistryAdvancedMode()));
+ }});
+
+ //
+ Map dataMap = ProxyConfigUtils.applyProxyConfigDataFromPillar(mockPillar);
+
+ //
+ assertEquals(DUMMY_PARENT_FQDN, dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertEquals(DUMMY_PROXY_PORT, dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertEquals(DUMMY_MAX_CACHE, dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertEquals(DUMMY_ADMIN_MAIL, dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+ assertEquals(DUMMY_ROOT_CA, dataMap.get(ProxyConfigUtils.ROOT_CA_FIELD));
+ assertEquals(
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ dataMap.get(ProxyConfigUtils.INTERMEDIATE_CAS_FIELD)
+ );
+ assertEquals(DUMMY_PROXY_CERT, dataMap.get(ProxyConfigUtils.PROXY_CERT_FIELD));
+ assertEquals(DUMMY_PROXY_KEY, dataMap.get(ProxyConfigUtils.PROXY_KEY_FIELD));
+
+ assertEquals(ProxyConfigUtils.SOURCE_MODE_REGISTRY, dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+ assertEquals(ProxyConfigUtils.REGISTRY_MODE_ADVANCED, dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+
+ assertEquals(expectedHttpdUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getPillarImageVariableName()));
+ assertEquals(expectedHttpdTag, dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getPillarTagVariableName()));
+
+ assertEquals(
+ expectedSaltBrokerUrl,
+ dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getPillarImageVariableName())
+ );
+ assertEquals(
+ expectedSaltBrokerTag,
+ dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getPillarTagVariableName())
+ );
+
+ assertEquals(expectedSquidUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getPillarImageVariableName()));
+ assertEquals(expectedSquidTag, dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getPillarTagVariableName()));
+
+ assertEquals(expectedSshUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getPillarImageVariableName()));
+ assertEquals(expectedSshTag, dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getPillarTagVariableName()));
+
+ assertEquals(expectedTftpdUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getPillarImageVariableName()));
+ assertEquals(expectedTftpdTag, dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getPillarTagVariableName()));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#applyProxyConfigDataFromPillar(Pillar)} method when the pillar returns
+ * full data in scope of registry simple mode.
+ */
+ @Test
+ public void testApplyProxyConfigDataFromPillarWhenRegistrySimpleMode() {
+ final String expectedHttpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_HTTPD);
+ final String expectedSaltBrokerUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SALT_BROKER);
+ final String expectedSquidUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SQUID);
+ final String expectedSshUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_SSH);
+ final String expectedTftpdUrl = getDummyUrl(ProxyContainerImagesEnum.PROXY_TFTPD);
+
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(createPillarMapWithRegistrySimpleMode()));
+ }});
+
+ //
+ Map dataMap = ProxyConfigUtils.applyProxyConfigDataFromPillar(mockPillar);
+
+ //
+ assertEquals(DUMMY_PARENT_FQDN, dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertEquals(DUMMY_PROXY_PORT, dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertEquals(DUMMY_MAX_CACHE, dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertEquals(DUMMY_ADMIN_MAIL, dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+ assertEquals(DUMMY_ROOT_CA, dataMap.get(ProxyConfigUtils.ROOT_CA_FIELD));
+ assertEquals(
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ dataMap.get(ProxyConfigUtils.INTERMEDIATE_CAS_FIELD)
+ );
+ assertEquals(DUMMY_PROXY_CERT, dataMap.get(ProxyConfigUtils.PROXY_CERT_FIELD));
+ assertEquals(DUMMY_PROXY_KEY, dataMap.get(ProxyConfigUtils.PROXY_KEY_FIELD));
+
+ assertEquals(ProxyConfigUtils.SOURCE_MODE_REGISTRY, dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+ assertEquals(ProxyConfigUtils.REGISTRY_MODE_ADVANCED, dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+
+ assertEquals(expectedHttpdUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getPillarImageVariableName()));
+ assertEquals(DUMMY_TAG, dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getPillarTagVariableName()));
+
+ assertEquals(
+ expectedSaltBrokerUrl,
+ dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getPillarImageVariableName())
+ );
+ assertEquals(DUMMY_TAG, dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getPillarTagVariableName()));
+
+ assertEquals(expectedSquidUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getPillarImageVariableName()));
+ assertEquals(DUMMY_TAG, dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getPillarTagVariableName()));
+
+ assertEquals(expectedSshUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getPillarImageVariableName()));
+ assertEquals(DUMMY_TAG, dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getPillarTagVariableName()));
+
+ assertEquals(expectedTftpdUrl, dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getPillarImageVariableName()));
+ assertEquals(DUMMY_TAG, dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getPillarTagVariableName()));
+ }
+
+ /**
+ * Tests the {@link ProxyConfigUtils#applyProxyConfigDataFromPillar(Pillar)} method when the pillar returns
+ * data in scope of RPM mode.
+ */
+ @Test
+ public void testApplyProxyConfigDataFromPillarWhenRpm() {
+ context.checking(new Expectations() {{
+ allowing(mockPillar).getPillar();
+ will(returnValue(createPillarMapWithRpm()));
+ }});
+
+ //
+ Map dataMap = ProxyConfigUtils.applyProxyConfigDataFromPillar(mockPillar);
+
+ //
+ assertEquals(DUMMY_PARENT_FQDN, dataMap.get(ProxyConfigUtils.PARENT_FQDN_FIELD));
+ assertEquals(DUMMY_PROXY_PORT, dataMap.get(ProxyConfigUtils.PROXY_PORT_FIELD));
+ assertEquals(DUMMY_MAX_CACHE, dataMap.get(ProxyConfigUtils.MAX_CACHE_FIELD));
+ assertEquals(DUMMY_ADMIN_MAIL, dataMap.get(ProxyConfigUtils.EMAIL_FIELD));
+ assertEquals(DUMMY_ROOT_CA, dataMap.get(ProxyConfigUtils.ROOT_CA_FIELD));
+ assertEquals(
+ List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2),
+ dataMap.get(ProxyConfigUtils.INTERMEDIATE_CAS_FIELD)
+ );
+ assertEquals(DUMMY_PROXY_CERT, dataMap.get(ProxyConfigUtils.PROXY_CERT_FIELD));
+ assertEquals(DUMMY_PROXY_KEY, dataMap.get(ProxyConfigUtils.PROXY_KEY_FIELD));
+
+ assertEquals(ProxyConfigUtils.SOURCE_MODE_RPM, dataMap.get(ProxyConfigUtils.SOURCE_MODE_FIELD));
+
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_MODE));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_URL));
+ assertNull(dataMap.get(ProxyConfigUtils.REGISTRY_BASE_TAG));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getPillarImageVariableName()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_HTTPD.getPillarTagVariableName()));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getPillarImageVariableName()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SALT_BROKER.getPillarTagVariableName()));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getPillarImageVariableName()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SQUID.getPillarTagVariableName()));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getPillarImageVariableName()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_SSH.getPillarTagVariableName()));
+
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getPillarImageVariableName()));
+ assertNull(dataMap.get(ProxyContainerImagesEnum.PROXY_TFTPD.getPillarTagVariableName()));
+ }
+
+
+ /**
+ * Creates a dummy pillar map with RPM data (ie without registries).
+ *
+ * @return the dummy pillar map
+ */
+ private Map createPillarMapWithRpm() {
+ Map pillarMap = new HashMap<>();
+ pillarMap.put(SERVER_ID_FIELD, DUMMY_SERVER_ID);
+ pillarMap.put(PROXY_FQDN_FIELD, DUMMY_PROXY_FQDN);
+ pillarMap.put(PARENT_FQDN_FIELD, DUMMY_PARENT_FQDN);
+ pillarMap.put(PROXY_PORT_FIELD, DUMMY_PROXY_PORT);
+ pillarMap.put(MAX_CACHE_FIELD, DUMMY_MAX_CACHE);
+ pillarMap.put(EMAIL_FIELD, DUMMY_ADMIN_MAIL);
+ pillarMap.put(ROOT_CA_FIELD, DUMMY_ROOT_CA);
+ pillarMap.put(PROXY_CERT_FIELD, DUMMY_PROXY_CERT);
+ pillarMap.put(PROXY_KEY_FIELD, DUMMY_PROXY_KEY);
+ pillarMap.put(INTERMEDIATE_CAS_FIELD, List.of(DUMMY_INTERMEDIATE_CA_1, DUMMY_INTERMEDIATE_CA_2));
+ return pillarMap;
+ }
+
+ /**
+ * Creates a dummy pillar map with registry data in advanced mode.
+ *
+ * @return the dummy pillar map
+ */
+ private Map createPillarMapWithRegistryAdvancedMode() {
+ Map pillarMap = createPillarMapWithRpm();
+
+ Map registriesList = new HashMap<>();
+ for (ProxyContainerImagesEnum image : ProxyContainerImagesEnum.values()) {
+ Map imageMap = new HashMap<>();
+ imageMap.put(PILLAR_REGISTRY_URL_ENTRY, getDummyUrl(image));
+ imageMap.put(PILLAR_REGISTRY_TAG_ENTRY, getDummyTag(image));
+ registriesList.put(image.getImageName(), imageMap);
+ }
+ pillarMap.put(PILLAR_REGISTRY_ENTRY, registriesList);
+ return pillarMap;
+ }
+
+ /**
+ * Creates a dummy pillar map with registry data in simple mode.
+ *
+ * @return the dummy pillar map
+ */
+ private Map createPillarMapWithRegistrySimpleMode() {
+ Map pillarMap = createPillarMapWithRpm();
+
+ Map registriesList = new HashMap<>();
+ for (ProxyContainerImagesEnum image : ProxyContainerImagesEnum.values()) {
+ Map imageMap = new HashMap<>();
+ imageMap.put(PILLAR_REGISTRY_URL_ENTRY, DUMMY_URL_PREFIX + image.getImageName());
+ imageMap.put(PILLAR_REGISTRY_TAG_ENTRY, DUMMY_TAG);
+ registriesList.put(image.getImageName(), imageMap);
+ }
+ pillarMap.put(PILLAR_REGISTRY_ENTRY, registriesList);
+ return pillarMap;
+ }
+}
+
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateAcquisitor.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateAcquisitor.java
index d86db1be484e..d65edca9c8ce 100644
--- a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateAcquisitor.java
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateAcquisitor.java
@@ -30,7 +30,6 @@
import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
import com.suse.proxy.ProxyContainerImagesEnum;
import com.suse.proxy.RegistryUrl;
-import com.suse.proxy.get.ProxyConfigGet;
import com.suse.proxy.model.ProxyConfig;
import org.apache.logging.log4j.LogManager;
@@ -39,7 +38,8 @@
import java.net.URISyntaxException;
/**
- * Acquires additional information from the request data
+ * Acquires information required for updating the proxy configuration
+ * Might these be just used for validation purposes or actually updating the proxy configuration
*/
public class ProxyConfigUpdateAcquisitor implements ProxyConfigUpdateContextHandler {
private static final Logger LOG = LogManager.getLogger(ProxyConfigUpdateAcquisitor.class);
@@ -66,7 +66,7 @@ private void acquireProxyMinion(ProxyConfigUpdateContext context) {
context.setProxyFqdn(ofNullable(minionServer.findPrimaryFqdn())
.map(ServerFQDN::getName)
.orElse(minionServer.getName()));
- context.setProxyConfig(new ProxyConfigGet().get(minionServer));
+ context.setProxyConfig(context.getProxyConfigGetFacade().getProxyConfig(minionServer));
}
});
}
@@ -74,7 +74,10 @@ private void acquireProxyMinion(ProxyConfigUpdateContext context) {
/**
* Acquires the certificates from the request or the current proxy configuration
- *
+ * In case the request specifies to keep the current certificates, the current proxy configuration is used.
+ * Two main reasons for this:
+ * 1) We want to keep the exact same certificates we have stored;
+ * 2) WebUi is getting truncated certificates data, that's also what we'll get back.
* @param context the context
*/
private void acquireCertificates(ProxyConfigUpdateContext context) {
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateApplySaltState.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateApplySaltState.java
index 464903e8ea81..f757c18753ea 100644
--- a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateApplySaltState.java
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateApplySaltState.java
@@ -71,9 +71,10 @@ else if (applySaltStateResponse.size() != 1) {
}
JsonObject jsonObject = jsonElement.getAsJsonObject();
for (String key : jsonObject.keySet()) {
- if (!jsonObject.get(key).getAsJsonObject().get("result").getAsBoolean()) {
+ JsonElement jsonElementChild = jsonObject.get(key);
+ if (!jsonElementChild.getAsJsonObject().get("result").getAsBoolean()) {
context.getErrorReport().register(FAIL_APPLY_MESSAGE);
- LOG.error(FAIL_APPLY_MESSAGE + " Failing entry: {}", jsonElement);
+ LOG.error(FAIL_APPLY_MESSAGE + " Failing entry: {}", jsonElementChild);
}
}
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateContext.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateContext.java
index 78e5334cc404..b2c956f8e8f2 100644
--- a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateContext.java
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateContext.java
@@ -26,6 +26,8 @@
import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
import com.suse.proxy.ProxyContainerImagesEnum;
import com.suse.proxy.RegistryUrl;
+import com.suse.proxy.get.ProxyConfigGetFacade;
+import com.suse.proxy.get.ProxyConfigGetFacadeImpl;
import com.suse.proxy.model.ProxyConfig;
import java.util.EnumMap;
@@ -33,8 +35,7 @@
import java.util.Map;
/**
- * This class the context that is passed through the chain of responsibility pattern.
- * Its main purpose is to hold the relevant data through the steps of the proxy config update process.
+ * This class holds relevant data through the steps of the proxy config update process.
*/
public class ProxyConfigUpdateContext {
@@ -46,6 +47,7 @@ public class ProxyConfigUpdateContext {
private final SystemManager systemManager;
private final User user;
private final SaltApi saltApi;
+ private final ProxyConfigGetFacade proxyConfigGetFacade;
// Acquired/computed data
private String proxyFqdn;
@@ -74,11 +76,31 @@ public ProxyConfigUpdateContext(
SystemManager systemManagerIn,
SaltApi saltApiIn,
User userIn
+ ) {
+ this(requestIn, systemManagerIn, saltApiIn, userIn, new ProxyConfigGetFacadeImpl());
+ }
+
+ /**
+ * Full params constructor
+ *
+ * @param requestIn the request
+ * @param systemManagerIn the system manager
+ * @param saltApiIn the salt API
+ * @param userIn the user
+ * @param proxyConfigGetFacadeIn the proxy config get facade
+ */
+ public ProxyConfigUpdateContext(
+ ProxyConfigUpdateJson requestIn,
+ SystemManager systemManagerIn,
+ SaltApi saltApiIn,
+ User userIn,
+ ProxyConfigGetFacade proxyConfigGetFacadeIn
) {
this.request = requestIn;
this.systemManager = systemManagerIn;
this.saltApi = saltApiIn;
this.user = userIn;
+ this.proxyConfigGetFacade = proxyConfigGetFacadeIn;
}
public ProxyConfigUpdateJson getRequest() {
@@ -89,42 +111,42 @@ public RhnErrorReport getErrorReport() {
return errorReport;
}
- public void setProxyFqdn(String proxyFqdnIn) {
- this.proxyFqdn = proxyFqdnIn;
- }
-
public String getProxyFqdn() {
return proxyFqdn;
}
- public Map getRegistryUrls() {
- return registryUrls;
+ public void setProxyFqdn(String proxyFqdnIn) {
+ this.proxyFqdn = proxyFqdnIn;
}
- public void setProxyMinion(MinionServer minionServerIn) {
- this.proxyMinion = minionServerIn;
+ public Map getRegistryUrls() {
+ return registryUrls;
}
public MinionServer getProxyMinion() {
return proxyMinion;
}
- public void setParentServer(Server server) {
- this.parentServer = server;
- }
-
- public void setProxyConfig(ProxyConfig proxyConfigIn) {
- this.proxyConfig = proxyConfigIn;
+ public void setProxyMinion(MinionServer minionServerIn) {
+ this.proxyMinion = minionServerIn;
}
public Server getParentServer() {
return parentServer;
}
+ public void setParentServer(Server server) {
+ this.parentServer = server;
+ }
+
public ProxyConfig getProxyConfig() {
return proxyConfig;
}
+ public void setProxyConfig(ProxyConfig proxyConfigIn) {
+ this.proxyConfig = proxyConfigIn;
+ }
+
public SystemManager getSystemManager() {
return systemManager;
}
@@ -133,14 +155,14 @@ public User getUser() {
return user;
}
- public void setProxyConfigFiles(Map proxyConfigFilesIn) {
- this.proxyConfigFiles = proxyConfigFilesIn;
- }
-
public Map getProxyConfigFiles() {
return proxyConfigFiles;
}
+ public void setProxyConfigFiles(Map proxyConfigFilesIn) {
+ this.proxyConfigFiles = proxyConfigFilesIn;
+ }
+
public String getRootCA() {
return rootCA;
}
@@ -184,5 +206,9 @@ public void setPillar(Pillar pillarIn) {
public SaltApi getSaltApi() {
return saltApi;
}
+
+ public ProxyConfigGetFacade getProxyConfigGetFacade() {
+ return proxyConfigGetFacade;
+ }
}
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFacade.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFacade.java
new file mode 100644
index 000000000000..a1aa832b74b1
--- /dev/null
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFacade.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2025 SUSE LLC
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+
+package com.suse.proxy.update;
+
+import com.redhat.rhn.domain.user.User;
+import com.redhat.rhn.manager.system.SystemManager;
+
+import com.suse.manager.webui.services.iface.SaltApi;
+import com.suse.manager.webui.utils.gson.ProxyConfigUpdateJson;
+
+public interface ProxyConfigUpdateFacade {
+ /**
+ * Update a proxy configuration to a proxy minion.
+ * @param request the proxy configuration update JSON with the new values
+ * @param systemManager the system manager
+ * @param saltApi the salt API
+ * @param user the user
+ */
+ void update(ProxyConfigUpdateJson request, SystemManager systemManager, SaltApi saltApi, User user);
+}
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdate.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFacadeImpl.java
similarity index 95%
rename from java/code/src/com/suse/proxy/update/ProxyConfigUpdate.java
rename to java/code/src/com/suse/proxy/update/ProxyConfigUpdateFacadeImpl.java
index 4482afdf3f1f..70ec6eba2217 100644
--- a/java/code/src/com/suse/proxy/update/ProxyConfigUpdate.java
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFacadeImpl.java
@@ -33,13 +33,13 @@
* These steps have a specific order and are executed in sequence.
* If an error occurs in any of these steps, the process halts and the errors are be reported.
*/
-public class ProxyConfigUpdate {
+public class ProxyConfigUpdateFacadeImpl implements ProxyConfigUpdateFacade {
private final List contextHandlerChain = new ArrayList<>();
/**
* Constructor
*/
- public ProxyConfigUpdate() {
+ public ProxyConfigUpdateFacadeImpl() {
this.contextHandlerChain.addAll(asList(
new ProxyConfigUpdateAcquisitor(),
new ProxyConfigUpdateValidation(),
@@ -58,6 +58,7 @@ public ProxyConfigUpdate() {
* @param saltApi the salt API
* @param user the user
*/
+ @Override
public void update(ProxyConfigUpdateJson request, SystemManager systemManager, SaltApi saltApi, User user) {
ProxyConfigUpdateContext context = new ProxyConfigUpdateContext(request, systemManager, saltApi, user);
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFileAcquisitor.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFileAcquisitor.java
index 091e82a08bfe..6483a4ae48ee 100644
--- a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFileAcquisitor.java
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateFileAcquisitor.java
@@ -105,7 +105,5 @@ null, null, null, new SSLCertManager())
LOG.error("Failed to create proxy container configuration", e);
context.getErrorReport().register("Failed to create proxy container configuration");
}
-
}
-
}
diff --git a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateRegistryPreConditions.java b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateRegistryPreConditions.java
index e9e9338aea6c..1697ee108420 100644
--- a/java/code/src/com/suse/proxy/update/ProxyConfigUpdateRegistryPreConditions.java
+++ b/java/code/src/com/suse/proxy/update/ProxyConfigUpdateRegistryPreConditions.java
@@ -70,7 +70,8 @@ public void handle(ProxyConfigUpdateContext context) {
registryUtils.getTags(context.getRegistryUrls().get(proxyImage));
}
catch (ParseException parseException) {
- LOG.error("Failed to get tags for: {} {}", proxyImage.getImageName(), context.getRegistryUrls().get(proxyImage));
+ LOG.error("Failed to get tags for: {} {}",
+ proxyImage.getImageName(), context.getRegistryUrls().get(proxyImage));
context.getErrorReport().register(
"Failed to get tags for: " + proxyImage.getImageName()
);
diff --git a/java/code/src/com/suse/rest/RestRequest.java b/java/code/src/com/suse/rest/RestRequest.java
index 5dac55cf3a51..09a657ead539 100644
--- a/java/code/src/com/suse/rest/RestRequest.java
+++ b/java/code/src/com/suse/rest/RestRequest.java
@@ -17,6 +17,9 @@
import java.util.Map;
+/**
+ * Class to represent a generic REST request.
+ */
public class RestRequest {
private final RestRequestMethodEnum method;
diff --git a/java/code/src/com/suse/rest/RestRequestAuthEnum.java b/java/code/src/com/suse/rest/RestRequestAuthEnum.java
index 61828df8e02e..ca16f0e79375 100644
--- a/java/code/src/com/suse/rest/RestRequestAuthEnum.java
+++ b/java/code/src/com/suse/rest/RestRequestAuthEnum.java
@@ -16,7 +16,7 @@
package com.suse.rest;
/**
- * Enum to represent the type of authentication required for a request.
+ * Enum to represent the types of authentication required for a request.
*/
public enum RestRequestAuthEnum {
NONE,
diff --git a/java/code/src/com/suse/rest/RestRequestBuilder.java b/java/code/src/com/suse/rest/RestRequestBuilder.java
index 74f519be426a..85337431d889 100644
--- a/java/code/src/com/suse/rest/RestRequestBuilder.java
+++ b/java/code/src/com/suse/rest/RestRequestBuilder.java
@@ -21,7 +21,7 @@
import java.util.Map;
/**
- * Class to build and execute a request.
+ * Builder for Rest request.
*/
@SuppressWarnings("checkstyle:VisibilityModifier")
public class RestRequestBuilder {
diff --git a/java/code/src/com/suse/rest/RestResponse.java b/java/code/src/com/suse/rest/RestResponse.java
index 2b9f1cd030de..6277b9b6a18f 100644
--- a/java/code/src/com/suse/rest/RestResponse.java
+++ b/java/code/src/com/suse/rest/RestResponse.java
@@ -24,7 +24,7 @@
import java.util.Map;
/**
- * Class to represent a response from a request.
+ * Class to represent a response from a Rest request.
*/
public class RestResponse {
private final int statusCode;
diff --git a/java/code/webapp/WEB-INF/nav/system_detail.xml b/java/code/webapp/WEB-INF/nav/system_detail.xml
index bbd09d80ef2a..49351e618866 100644
--- a/java/code/webapp/WEB-INF/nav/system_detail.xml
+++ b/java/code/webapp/WEB-INF/nav/system_detail.xml
@@ -10,8 +10,11 @@
/rhn/systems/details/SystemRemoteCommand.do
-
-
+
+ /rhn/manager/systems/details/proxy-config
+
+
+
@@ -213,11 +216,6 @@
/rhn/manager/systems/details/formulas
-
- /rhn/manager/systems/details/proxy-config
-
-
-
/rhn/manager/systems/details/ansible/control-node
diff --git a/schema/spacewalk/common/data/rhnServerServerGroupArchCompat.sql b/schema/spacewalk/common/data/rhnServerServerGroupArchCompat.sql
index 8ad69c29cdb3..d57d124aaf96 100644
--- a/schema/spacewalk/common/data/rhnServerServerGroupArchCompat.sql
+++ b/schema/spacewalk/common/data/rhnServerServerGroupArchCompat.sql
@@ -939,26 +939,168 @@ insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
lookup_sg_type('peripheral_server'));
-- proxy_entitled compatibilities
-DO $$
-DECLARE
- loop_server_arch_id INT;
- proxy_sg_type_id INT;
-BEGIN
- proxy_sg_type_id := lookup_sg_type('proxy_entitled');
-
- FOR loop_server_arch_id IN
- SELECT id FROM rhnserverarch
- LOOP
- INSERT INTO rhnServerServerGroupArchCompat (server_arch_id, server_group_type)
- SELECT
- loop_server_arch_id,
- proxy_sg_type_id
- WHERE NOT EXISTS (
- SELECT 1
- FROM rhnServerServerGroupArchCompat AS rs
- WHERE rs.server_arch_id = loop_server_arch_id AND rs.server_group_type = proxy_sg_type_id
- );
- END LOOP;
-END $$;
-
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('i386-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('i386-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('i486-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('i586-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('i686-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('athlon-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('alpha-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('alpha-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('alphaev6-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ia64-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ia64-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('sparc-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('sparc-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('sparcv9-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('sparc64-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('s390-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('s390-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('s390x-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ppc-redhat-linux'),
+ lookup_sg_type('proxy_entitled'))
+ ;
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('aarch64-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('armv7l-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('armv5tejl-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('armv6l-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('armv6hl-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('powerpc-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ppc64-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ppc64le-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('pSeries-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('iSeries-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('x86_64-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ppc64iseries-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ppc64pseries-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('ia32e-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('amd64-redhat-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('amd64-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('arm-debian-linux'),
+ lookup_sg_type('proxy_entitled'))
+ ;
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('armv6l-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('mips-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('armv7l-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('cloud'),
+ lookup_sg_type('proxy_entitled
+ l_server'));
+insert into rhnServerServerGroupArchCompat ( server_arch_id, server_group_type )
+ values (lookup_server_arch('arm64-debian-linux'),
+ lookup_sg_type('proxy_entitled'));
+
commit;
diff --git a/schema/spacewalk/postgres/packages/rhn_entitlements.pkb b/schema/spacewalk/postgres/packages/rhn_entitlements.pkb
index 5fb7741c6fa0..6418d4791413 100644
--- a/schema/spacewalk/postgres/packages/rhn_entitlements.pkb
+++ b/schema/spacewalk/postgres/packages/rhn_entitlements.pkb
@@ -1,5 +1,6 @@
-- oracle equivalent source sha1 0690aebc316b2ea8195ae4804ec450d5d301057c
--
+-- Copyright (c) 2016--2025 SUSE LLC
-- Copyright (c) 2008--2015 Red Hat, Inc.
--
-- This software is licensed to you under the GNU General Public License,
@@ -238,6 +239,7 @@ as $$
when 'monitoring_entitled' then 'Monitoring'
when 'ansible_control_node' then 'Ansible'
when 'peripheral_server' then 'Peripheral'
+ when 'proxy_entitled' then 'Proxy'
end );
perform rhn_server.insert_into_servergroup (server_id_in, sgid);
diff --git a/schema/spacewalk/upgrade/susemanager-schema-5.1.2-to-susemanager-schema-5.1.3/012-create_new_org.sql b/schema/spacewalk/upgrade/susemanager-schema-5.1.2-to-susemanager-schema-5.1.3/012-create_new_org.sql
new file mode 100644
index 000000000000..7c0f1c97e457
--- /dev/null
+++ b/schema/spacewalk/upgrade/susemanager-schema-5.1.2-to-susemanager-schema-5.1.3/012-create_new_org.sql
@@ -0,0 +1,261 @@
+--
+-- Copyright (c) 2013--2025 SUSE LLC
+-- Copyright (c) 2008--2012 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+
+create or replace function create_new_org
+(
+ name_in in varchar,
+ password_in in varchar
+ --org_id_out out number
+) returns numeric
+as
+$$
+declare
+ ug_type numeric;
+ group_val numeric;
+ new_org_id numeric;
+ org_id_out numeric;
+begin
+
+ select nextval('web_customer_id_seq') into new_org_id from dual;
+
+ insert into web_customer (
+ id, name
+ ) values (
+ new_org_id, name_in
+ );
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'org_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'Organization Administrators',
+ 'Organization Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'system_group_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'System Group Administrators',
+ 'System Group Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'activation_key_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'Activation Key Administrators',
+ 'Activation Key Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'channel_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'Channel Administrators',
+ 'Channel Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+
+ if new_org_id = 1 then
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'satellite_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'SUSE Manager Administrators',
+ 'SUSE Manager Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+ end if;
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'config_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'Configuration Administrators',
+ 'Configuration Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ select id
+ into ug_type
+ from rhnUserGroupType
+ where label = 'image_admin';
+
+ insert into rhnUserGroup (
+ id, name,
+ description,
+ max_members, group_type, org_id
+ ) values (
+ group_val, 'Image Administrators',
+ 'Image Administrators for Org ' || name_in,
+ NULL, ug_type, new_org_id
+ );
+
+ select nextval('rhn_user_group_id_seq') into group_val from dual;
+
+ -- there aren't any users yet, so we don't need to update
+ -- rhnUserServerPerms
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'bootstrap_entitled';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'enterprise_entitled';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'salt_entitled';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'foreign_entitled';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'virtualization_host';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'container_build_host';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'osimage_build_host';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'monitoring_entitled';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'ansible_control_node';
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'peripheral_server';
+
+
+ insert into rhnServerGroup
+ ( id, name, description, group_type, org_id )
+ select nextval('rhn_server_group_id_seq'), sgt.name, sgt.name,
+ sgt.id, new_org_id
+ from rhnServerGroupType sgt
+ where sgt.label = 'proxy_entitled';
+
+ insert into suseImageStore (id, label, uri, store_type_id, org_id)
+ values (
+ nextval('suse_imgstore_id_seq'),
+ 'SUSE Manager OS Image Store',
+ new_org_id || '/',
+ (SELECT id FROM suseImageStoreType WHERE label = 'os_image'),
+ new_org_id
+ );
+
+ org_id_out := new_org_id;
+
+ -- Returning the value of OUT parameter
+ return org_id_out;
+
+end;
+$$
+language plpgsql;
diff --git a/susemanager-utils/susemanager-sls/salt/apply_proxy_config.sls b/susemanager-utils/susemanager-sls/salt/proxy/apply_proxy_config.sls
similarity index 59%
rename from susemanager-utils/susemanager-sls/salt/apply_proxy_config.sls
rename to susemanager-utils/susemanager-sls/salt/proxy/apply_proxy_config.sls
index 44395a037bbc..710ccd7358de 100644
--- a/susemanager-utils/susemanager-sls/salt/apply_proxy_config.sls
+++ b/susemanager-utils/susemanager-sls/salt/proxy/apply_proxy_config.sls
@@ -3,12 +3,9 @@
{%- set mgrpxy_operation = 'install' if not mgrpxy_installed or 'Error: no installed proxy detected' in mgrpxy_status_output else 'upgrade' %}
{%- set transactional = grains['transactional'] %}
-podman_installed_running:
+podman_installed:
pkg.installed:
- name: podman
- service.running:
- - name: podman
- - enable: True
mgrpxy_installed:
pkg.installed:
@@ -66,13 +63,30 @@ mgrpxy_installed:
{{ pillar['ssh']['server_ssh_push_pub'] | replace('\\n', '\n') | indent(12) }}
+{% set args = [] %}
+{% if pillar['httpd_image'] is defined and pillar['httpd_tag'] is defined %}
+ {% do args.append("--httpd-image " ~ pillar['httpd_image'] ~ " --httpd-tag " ~ pillar['httpd_tag']) %}
+{% endif %}
+{% if pillar['saltbroker_image'] is defined and pillar['saltbroker_tag'] is defined %}
+ {% do args.append("--saltbroker-image " ~ pillar['saltbroker_image'] ~ " --saltbroker-tag " ~ pillar['saltbroker_tag']) %}
+{% endif %}
+{% if pillar['squid_image'] is defined and pillar['squid_tag'] is defined %}
+ {% do args.append("--squid-image " ~ pillar['squid_image'] ~ " --squid-tag " ~ pillar['squid_tag']) %}
+{% endif %}
+{% if pillar['ssh_image'] is defined and pillar['ssh_tag'] is defined %}
+ {% do args.append("--ssh-image " ~ pillar['ssh_image'] ~ " --ssh-tag " ~ pillar['ssh_tag']) %}
+{% endif %}
+{% if pillar['tftpd_image'] is defined and pillar['tftpd_tag'] is defined %}
+ {% do args.append("--tftpd-image " ~ pillar['tftpd_image'] ~ " --tftpd-tag " ~ pillar['tftpd_tag']) %}
+{% endif %}
+
{% if transactional %}
# If we're on a transactional system, we'll install mgrpxy apply as a service that
# executes the mgrpxy install/update command after next reboot
-/etc/systemd/system/apply_mgrpxy.service:
+/etc/systemd/system/apply_proxy_config.service:
file.managed:
- - name: /etc/systemd/system/apply_mgrpxy.service
+ - name: /etc/systemd/system/apply_proxy_config.service
- user: root
- group: root
- mode: 664
@@ -86,19 +100,13 @@ mgrpxy_installed:
[Service]
Type=oneshot
- ExecStart=/bin/bash -c 'mgrpxy {{ mgrpxy_operation }} podman --logLevel debug \
- {% if pillar['httpd_image'] is defined and pillar['httpd_tag'] is defined %}--httpd-image {{ pillar['httpd_image'] }} --httpd-tag {{ pillar['httpd_tag'] }} {% endif %} \
- {% if pillar['saltbroker_image'] is defined and pillar['saltbroker_tag'] is defined %}--saltbroker-image {{ pillar['saltbroker_image'] }} --saltbroker-tag {{ pillar['saltbroker_tag'] }} {% endif %} \
- {% if pillar['squid_image'] is defined and pillar['squid_tag'] is defined %}--squid-image {{ pillar['squid_image'] }} --squid-tag {{ pillar['squid_tag'] }} {% endif %} \
- {% if pillar['ssh_image'] is defined and pillar['ssh_tag'] is defined %}--ssh-image {{ pillar['ssh_image'] }} --ssh-tag {{ pillar['ssh_tag'] }} {% endif %} \
- {% if pillar['tftpd_image'] is defined and pillar['tftpd_tag'] is defined %}--tftpd-image {{ pillar['tftpd_image'] }} --tftpd-tag {{ pillar['tftpd_tag'] }} {% endif %} \
- 2>&1 | tee -a /var/log/mgrpxy_install.log'
-
+ ExecStart=/bin/bash -c 'mgrpxy {{ mgrpxy_operation }} podman --logLevel debug {{ args | join(" ") }} 2>&1 | tee -a /var/log/mgrpxy_install.log'
+
ExecStartPost=/bin/bash -c 'STATUS_OUTPUT=$(mgrpxy status 2>&1); \
echo "$STATUS_OUTPUT" | tee -a /var/log/mgrpxy_install.log; \
if ! echo "$STATUS_OUTPUT" | grep -q "Error: no installed proxy detected"; then \
echo "mgrpxy was successfully {{ mgrpxy_operation }}ed. Removing apply mgrpxy service and configuration file." | tee -a /var/log/mgrpxy_install.log; \
- rm -f /etc/systemd/system/apply_mgrpxy.service; \
+ rm -f /etc/systemd/system/apply_proxy_config.service; \
else \
echo "mgrpxy status check failed. Service file will remain for troubleshooting." | tee -a /var/log/mgrpxy_install.log; \
fi'
@@ -106,13 +114,13 @@ mgrpxy_installed:
[Install]
WantedBy=multi-user.target
-# The system will run this service to enable apply_mgrpxy.service after reboot
-enable_apply_mgrpxy_service:
+# The system will run this service to enable apply_proxy_config.service after reboot
+enable_apply_proxy_config_service:
service.running:
- - name: apply_mgrpxy.service
+ - name: apply_proxy_config.service
- enable: True
- require:
- - file: /etc/systemd/system/apply_mgrpxy.service
+ - file: /etc/systemd/system/apply_proxy_config.service
- file: /etc/uyuni/proxy/config.yaml
- file: /etc/uyuni/proxy/httpd.yaml
- file: /etc/uyuni/proxy/ssh.yaml
@@ -123,19 +131,14 @@ enable_apply_mgrpxy_service:
apply_proxy_configuration:
cmd.run:
- name: >
- mgrpxy {{ mgrpxy_operation }} podman --logLevel debug \
- {% if pillar['httpd_image'] is defined and pillar['httpd_tag'] is defined %} --httpd-image {{ pillar['httpd_image'] }} --httpd-tag {{ pillar['httpd_tag'] }} {% endif %} \
- {% if pillar['saltbroker_image'] is defined and pillar['saltbroker_tag'] is defined %} --saltbroker-image {{ pillar['saltbroker_image'] }} --saltbroker-tag {{ pillar['saltbroker_tag'] }} {% endif %} \
- {% if pillar['squid_image'] is defined and pillar['squid_tag'] is defined %} --squid-image {{ pillar['squid_image'] }} --squid-tag {{ pillar['squid_tag'] }} {% endif %} \
- {% if pillar['ssh_image'] is defined and pillar['ssh_tag'] is defined %} --ssh-image {{ pillar['ssh_image'] }} --ssh-tag {{ pillar['ssh_tag'] }} {% endif %} \
- {% if pillar['tftpd_image'] is defined and pillar['tftpd_tag'] is defined %} --tftpd-image {{ pillar['tftpd_image'] }} --tftpd-tag {{ pillar['tftpd_tag'] }} {% endif %} \
- > 2>&1 | tee -a /var/log/mgrpxy_install.log
+ mgrpxy {{ mgrpxy_operation }} podman --logLevel debug {{ args | join(" ") }}
+ 2>&1 | tee -a /var/log/mgrpxy_install.log
- shell: /bin/bash
- require:
- file: /etc/uyuni/proxy/config.yaml
- file: /etc/uyuni/proxy/httpd.yaml
- file: /etc/uyuni/proxy/ssh.yaml
- - service: podman_installed_running
+ - pkg: podman_installed
- pkg: mgrpxy_installed
{%- endif %}
diff --git a/web/html/src/manager/minion/proxy/proxy-config.tsx b/web/html/src/manager/minion/proxy/proxy-config.tsx
index 328c4ed84f6f..6372a8f4157e 100644
--- a/web/html/src/manager/minion/proxy/proxy-config.tsx
+++ b/web/html/src/manager/minion/proxy/proxy-config.tsx
@@ -10,7 +10,7 @@ import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput
import { unflattenModel } from "components/input/form-utils";
import { Radio } from "components/input/radio/Radio";
import { Text } from "components/input/text/Text";
-import { Panel } from "components/panels/Panel";
+import { Messages } from "components/messages/messages";
import { TopPanel } from "components/panels/TopPanel";
import Validation from "components/validation";
@@ -36,13 +36,9 @@ enum RegistryMode {
type ProxyConfigModel = {
rootCA: string;
- rootCA_safe?: string;
proxyCertificate: string;
- proxyCertificate_safe?: string;
proxyKey: string;
- proxyKey_safe?: string;
intermediateCAs?: string[];
- intermediateCAs_safe?: string[];
proxyAdminEmail: string;
maxSquidCacheSize: string;
parentFQDN: string;
@@ -130,7 +126,13 @@ const tagMapping = {
registryTftpdURL: "registryTftpdTag",
};
-export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFailMessage }: ProxyConfigProps) {
+export function ProxyConfig({
+ serverId,
+ isUyuni,
+ parents,
+ currentConfig,
+ initFailMessage,
+}: Readonly) {
const [messages, setMessages] = useState([]);
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState();
@@ -138,8 +140,7 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
const [errors, setErrors] = useState({});
const [tagOptions, setTagOptions] = useState({});
- const showUseCertsMode =
- currentConfig.rootCA_safe || currentConfig.proxyKey_safe || currentConfig.proxyCertificate_safe;
+ const hasExistingConfig = currentConfig !== undefined && Object.keys(currentConfig).length > 0;
const originalConfig = { ...currentConfig };
const [model, setModel] = useState(() => {
@@ -148,13 +149,6 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
...currentConfig,
};
- if (showUseCertsMode) {
- return {
- ...initialModel,
- useCertsMode: UseCertsMode.Keep,
- };
- }
-
return initialModel;
});
@@ -162,6 +156,8 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
if (currentConfig.sourceMode === SourceMode.RPM) {
//work-around to trigger validation for filled forms using RPM
retrieveRegistryTags(currentConfig, null);
+ } else if (currentConfig.registryBaseURL) {
+ retrieveRegistryTags(currentConfig, "registryBaseURL");
} else {
imageNames.forEach((url) => {
if (currentConfig[url]) {
@@ -302,7 +298,9 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
const restoreRegistryInputs = () => {
setModel({
...model,
- registryMode: RegistryMode.Advanced,
+ registryMode: originalConfig.registryMode,
+ registryBaseURL: originalConfig.registryBaseURL,
+ registryBaseTag: originalConfig.registryBaseTag,
registryHttpdURL: originalConfig.registryHttpdURL,
registryHttpdTag: originalConfig.registryHttpdTag,
registrySaltbrokerURL: originalConfig.registrySaltbrokerURL,
@@ -322,16 +320,12 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
}
};
- const onChangeRegistryeMode = (e, v) => {
- if (RegistryMode.Advanced === v && Object.keys(originalConfig).length > 0) {
+ const onChangeRegistryMode = (e, v) => {
+ if (originalConfig.registryMode === v && Object.keys(originalConfig).length > 0) {
restoreRegistryInputs();
}
};
- const getMinionNames = (data: any[] = []) => {
- return Array.from(new Set(data.map((item) => item.name))).sort();
- };
-
const useDebounce = (callback: (...args: any) => any, timeoutMs: number) =>
useCallback(debounce(callback, timeoutMs), []);
@@ -413,7 +407,7 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
placeholder={t("e.g., server.domain.com")}
labelClass="col-md-3"
divClass="col-md-6"
- options={getMinionNames(parents)}
+ options={parents}
isClearable={true}
/>
- {showUseCertsMode && (
+ {hasExistingConfig && (
0 && model.useCertsMode === UseCertsMode.Keep && (
<>
-
-
- {(currentConfig.intermediateCAs_safe || []).map((ca, index) => (
-
- ))}
-
-
-
+
+
+
>
)}
{(currentConfig === undefined || model.useCertsMode === UseCertsMode.Replace) && (
@@ -602,7 +560,7 @@ export function ProxyConfig({ serverId, isUyuni, parents, currentConfig, initFai
{ label: t("Simple"), value: RegistryMode.Simple },
{ label: t("Advanced"), value: RegistryMode.Advanced },
]}
- onChange={onChangeRegistryeMode}
+ onChange={onChangeRegistryMode}
/>
{model.registryMode === RegistryMode.Simple && (
<>