diff --git a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java index a2267cadd947..76c24394ec21 100644 --- a/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java +++ b/java/code/src/com/redhat/rhn/domain/server/ServerFactory.java @@ -40,6 +40,7 @@ import com.redhat.rhn.manager.system.UpdateBaseChannelCommand; import com.suse.manager.model.maintenance.MaintenanceSchedule; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; @@ -115,6 +116,10 @@ public static void removeCustomDataValues(Server server) { SINGLETON.removeObject(value); } server.getCustomDataValues().clear(); + server.asMinionServer().ifPresent(minion -> { + MinionPillarManager.INSTANCE.generatePillar(minion, false, + MinionPillarManager.PillarSubset.CUSTOM_INFO); + }); } /** @@ -129,6 +134,10 @@ public static void removeCustomDataValue(Server server, CustomDataKey key) { if (value != null) { SINGLETON.removeObject(value); } + server.asMinionServer().ifPresent(minion -> { + MinionPillarManager.INSTANCE.generatePillar(minion, false, + MinionPillarManager.PillarSubset.CUSTOM_INFO); + }); } /** @@ -682,7 +691,13 @@ public static void removeCustomKey(CustomDataKey keyIn) { List values = lookupCustomDataValues(keyIn); for (Iterator itr = values.iterator(); itr.hasNext();) { CustomDataValue value = (CustomDataValue) itr.next(); + Server server = value.getServer(); + server.getCustomDataValues().remove(value); SINGLETON.removeObject(value); + server.asMinionServer().ifPresent(minion -> { + MinionPillarManager.INSTANCE.generatePillar(minion, false, + MinionPillarManager.PillarSubset.CUSTOM_INFO); + }); } SINGLETON.removeObject(keyIn); diff --git a/java/code/src/com/redhat/rhn/frontend/action/systems/sdc/UpdateCustomDataAction.java b/java/code/src/com/redhat/rhn/frontend/action/systems/sdc/UpdateCustomDataAction.java index 7095255ae778..44b9dea8414c 100644 --- a/java/code/src/com/redhat/rhn/frontend/action/systems/sdc/UpdateCustomDataAction.java +++ b/java/code/src/com/redhat/rhn/frontend/action/systems/sdc/UpdateCustomDataAction.java @@ -27,6 +27,7 @@ import com.redhat.rhn.frontend.struts.RhnValidationHelper; import com.redhat.rhn.frontend.struts.StrutsDelegate; import com.redhat.rhn.manager.system.SystemManager; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; @@ -123,16 +124,21 @@ public ActionForward execute(ActionMapping mapping, return getStrutsDelegate().forwardParams( mapping.findForward(RhnHelper.DEFAULT_FORWARD), params); } - server.addCustomDataValue(key.getLabel(), (String)form.get(VAL_PARAM), user); if (cdv == null) { cdv = new CustomDataValue(); cdv.setKey(key); - cdv.setValue((String)form.get(VAL_PARAM)); + cdv.setCreated(new Date()); + cdv.setCreator(user); } + cdv.setValue((String)form.get(VAL_PARAM)); cdv.setModified(new Date()); - cdv.setCreated(new Date()); - cdv.setCreator(user); cdv.setLastModifier(user); + server.addCustomDataValue(cdv); + server.asMinionServer().ifPresent(minion -> { + MinionPillarManager.INSTANCE.generatePillar(minion, false, + MinionPillarManager.PillarSubset.CUSTOM_INFO); + }); + request.setAttribute(VAL_PARAM, form.get(VAL_PARAM)); return getStrutsDelegate().forwardParams(mapping.findForward("updated"), params); diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/SystemHandler.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/SystemHandler.java index 1feb9bd3711e..45a7916547f2 100644 --- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/SystemHandler.java +++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/SystemHandler.java @@ -170,6 +170,7 @@ import com.redhat.rhn.manager.token.ActivationKeyManager; import com.redhat.rhn.taskomatic.TaskomaticApi; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import com.suse.manager.webui.utils.gson.BootstrapParameters; import org.apache.commons.lang3.StringUtils; @@ -2013,6 +2014,11 @@ public int setCustomValues(User loggedInUser, Integer sid, Map v } } + server.asMinionServer().ifPresent(minion -> { + MinionPillarManager.INSTANCE.generatePillar(minion, false, + MinionPillarManager.PillarSubset.CUSTOM_INFO); + }); + // If we skipped any keys, we need to throw an exception and let the user know. if (skippedKeys.size() > 0) { // We need to throw an exception. Append each undefined key to the diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/test/SystemHandlerTest.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/test/SystemHandlerTest.java index 261f7787bd6d..40c0568e4303 100644 --- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/test/SystemHandlerTest.java +++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/test/SystemHandlerTest.java @@ -151,7 +151,11 @@ import org.jmock.imposters.ByteBuddyClassImposteriser; import org.jmock.integration.junit3.JUnit3Mockery; import org.jmock.lib.concurrent.Synchroniser; +import org.yaml.snakeyaml.Yaml; +import java.io.FileInputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -170,6 +174,9 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import static com.suse.manager.webui.services.SaltConstants.PILLAR_DATA_FILE_PREFIX; +import static com.suse.manager.webui.services.SaltConstants.PILLAR_DATA_FILE_EXT; + public class SystemHandlerTest extends BaseHandlerTestCase { private TaskomaticApi taskomaticApi = new TaskomaticApi(); @@ -1073,8 +1080,27 @@ private String getLongTestString() { return longString.toString(); } + private Map readCustomInfoPillar(MinionServer minion) throws Exception { + Path filePath = tmpPillarRoot.resolve( + PILLAR_DATA_FILE_PREFIX + "_" + + minion.getMinionId() + "_custom_info." + + PILLAR_DATA_FILE_EXT); + + assertTrue(Files.exists(filePath)); + + Map map; + try (FileInputStream fi = new FileInputStream(filePath.toFile())) { + map = new Yaml().loadAs(fi, Map.class); + } + + assertTrue(map.containsKey("custom_info")); + map = (Map)map.get("custom_info"); + + return map; + } + public void testCustomDataValues() throws Exception { - Server server = ServerFactoryTest.createTestServer(admin); + MinionServer server = MinionServerFactoryTest.createTestMinionServer(admin); CustomDataKey testKey = CustomDataKeyTest.createTestCustomDataKey(admin); // setCustomValues @@ -1105,6 +1131,11 @@ public void testCustomDataValues() throws Exception { assertEquals(val2, val.getValue()); assertEquals(1, setResult); + Map pillar = readCustomInfoPillar(server); + + assertTrue(pillar.containsKey(keyLabel)); + assertEquals(val2, pillar.get(keyLabel)); + // try to set custom values with some undefined keys valuesToSet.put(fooKey, val1); try { @@ -1138,6 +1169,10 @@ public void testCustomDataValues() throws Exception { val = server.getCustomDataValue(testKey); assertNotNull(val); + pillar = readCustomInfoPillar(server); + assertTrue(pillar.containsKey(keyLabel)); + assertEquals(val2, pillar.get(keyLabel)); + result = handler.getCustomValues(admin, server.getId().intValue()); assertEquals(1, result.size()); @@ -1151,6 +1186,13 @@ public void testCustomDataValues() throws Exception { assertEquals(1, setResult); val = server.getCustomDataValue(testKey); assertNull(val); + + Path filePath = tmpPillarRoot.resolve( + PILLAR_DATA_FILE_PREFIX + "_" + + server.getMinionId() + "_custom_info." + + PILLAR_DATA_FILE_EXT); + + assertFalse(Files.exists(filePath)); } public void testListUserSystems() throws Exception { diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/test/BaseHandlerTestCase.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/test/BaseHandlerTestCase.java index 99f9b39ca3a6..81f1ce51a399 100644 --- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/test/BaseHandlerTestCase.java +++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/test/BaseHandlerTestCase.java @@ -23,9 +23,7 @@ import com.redhat.rhn.testing.TestUtils; import com.redhat.rhn.testing.UserTestUtils; -import com.suse.manager.webui.services.pillar.MinionGeneralPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionGroupMembershipPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import com.suse.manager.webui.services.SaltStateGeneratorService; import java.nio.file.Files; @@ -48,10 +46,6 @@ public class BaseHandlerTestCase extends RhnBaseTestCase { protected String satAdminKey; protected Path tmpPillarRoot; protected Path tmpSaltRoot; - protected MinionPillarFileManager minionGroupMembershipPillarFileManager = - new MinionPillarFileManager(new MinionGroupMembershipPillarGenerator()); - protected MinionPillarFileManager minionGeneralPillarFileManager = - new MinionPillarFileManager(new MinionGeneralPillarGenerator()); @Override public void setUp() throws Exception { @@ -84,8 +78,7 @@ public void setUp() throws Exception { tmpPillarRoot = Files.createTempDirectory("pillar"); tmpSaltRoot = Files.createTempDirectory("salt"); - minionGroupMembershipPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); - minionGeneralPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); + MinionPillarManager.INSTANCE.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); SaltStateGeneratorService.INSTANCE.setSuseManagerStatesFilesRoot(tmpSaltRoot .toAbsolutePath()); Files.createDirectory(tmpSaltRoot.resolve(SALT_CONFIG_STATES_DIR)); diff --git a/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java b/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java index 06cc4554cecc..68f87be8f259 100644 --- a/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java +++ b/java/code/src/com/redhat/rhn/manager/system/ServerGroupManager.java @@ -31,8 +31,7 @@ import com.redhat.rhn.domain.user.UserFactory; import com.suse.manager.webui.services.SaltStateGeneratorService; -import com.suse.manager.webui.services.pillar.MinionGroupMembershipPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import com.suse.utils.Opt; import org.apache.log4j.Logger; @@ -54,17 +53,6 @@ public class ServerGroupManager { /** Logger */ private static final Logger LOG = Logger.getLogger(ServerGroupManager.class); - private MinionPillarFileManager minionGroupMembershipPillarFileManager = - new MinionPillarFileManager(new MinionGroupMembershipPillarGenerator()); - - /** - * Only used for unit tests. - * @param pillarFileManagerIn to set - */ - public void setMinionGroupMembershipPillarFileManager(MinionPillarFileManager pillarFileManagerIn) { - this.minionGroupMembershipPillarFileManager = pillarFileManagerIn; - } - /** * Lookup a ServerGroup by ID and organization. * @param id Server group id @@ -350,7 +338,8 @@ public void addServers(ServerGroup sg, Collection servers, User loggedIn */ public void updatePillarAfterGroupUpdateForServers(Collection servers) { servers.stream().map(server -> server.asMinionServer()).flatMap(Opt::stream) - .forEach(this.minionGroupMembershipPillarFileManager::updatePillarFile); + .forEach(s -> MinionPillarManager.INSTANCE.generatePillar(s, false, + MinionPillarManager.PillarSubset.GROUP_MEMBERSHIP)); } /** diff --git a/java/code/src/com/redhat/rhn/manager/system/entitling/SystemEntitler.java b/java/code/src/com/redhat/rhn/manager/system/entitling/SystemEntitler.java index d0d74099d9c2..5ac2e5db5357 100644 --- a/java/code/src/com/redhat/rhn/manager/system/entitling/SystemEntitler.java +++ b/java/code/src/com/redhat/rhn/manager/system/entitling/SystemEntitler.java @@ -45,8 +45,7 @@ import com.suse.manager.webui.services.iface.SaltApi; import com.suse.manager.webui.services.iface.VirtManager; import com.suse.manager.webui.services.impl.SaltSSHService; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; -import com.suse.manager.webui.services.pillar.MinionVirtualizationPillarGenerator; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.log4j.Logger; @@ -138,7 +137,8 @@ else if (EntitlementManager.OSIMAGE_BUILD_HOST.equals(ent)) { if (wasVirtEntitled && !EntitlementManager.VIRTUALIZATION.equals(ent) || !wasVirtEntitled && EntitlementManager.VIRTUALIZATION.equals(ent)) { this.updateLibvirtEngine(minion); - new MinionPillarFileManager(new MinionVirtualizationPillarGenerator()).updatePillarFile(minion); + MinionPillarManager.INSTANCE.generatePillar(minion, false, + MinionPillarManager.PillarSubset.VIRTUALIZATION); } if (EntitlementManager.MONITORING.equals(ent)) { diff --git a/java/code/src/com/redhat/rhn/manager/system/entitling/SystemUnentitler.java b/java/code/src/com/redhat/rhn/manager/system/entitling/SystemUnentitler.java index 33cc0752b374..2da31a6ed35a 100644 --- a/java/code/src/com/redhat/rhn/manager/system/entitling/SystemUnentitler.java +++ b/java/code/src/com/redhat/rhn/manager/system/entitling/SystemUnentitler.java @@ -25,8 +25,7 @@ import com.suse.manager.webui.services.iface.MonitoringManager; import com.suse.manager.webui.services.iface.VirtManager; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; -import com.suse.manager.webui.services.pillar.MinionVirtualizationPillarGenerator; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.log4j.Logger; @@ -101,7 +100,8 @@ public void removeServerEntitlement(Server server, Entitlement ent) { if (EntitlementManager.VIRTUALIZATION.equals(ent)) { virtManager.updateLibvirtEngine(s); - new MinionPillarFileManager(new MinionVirtualizationPillarGenerator()).updatePillarFile(s); + MinionPillarManager.INSTANCE.generatePillar(s, false, + MinionPillarManager.PillarSubset.VIRTUALIZATION); } }); } diff --git a/java/code/src/com/redhat/rhn/testing/BaseTestCaseWithUser.java b/java/code/src/com/redhat/rhn/testing/BaseTestCaseWithUser.java index 859b3aefd05f..7151fe575ac5 100644 --- a/java/code/src/com/redhat/rhn/testing/BaseTestCaseWithUser.java +++ b/java/code/src/com/redhat/rhn/testing/BaseTestCaseWithUser.java @@ -19,9 +19,7 @@ import com.redhat.rhn.domain.user.User; import com.suse.manager.webui.services.SaltStateGeneratorService; -import com.suse.manager.webui.services.pillar.MinionGeneralPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionGroupMembershipPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.commons.io.FileUtils; @@ -39,10 +37,6 @@ public abstract class BaseTestCaseWithUser extends RhnBaseTestCase { private boolean committed = false; protected Path tmpPillarRoot; protected Path tmpSaltRoot; - protected MinionPillarFileManager minionGroupMembershipPillarFileManager = - new MinionPillarFileManager(new MinionGroupMembershipPillarGenerator()); - protected MinionPillarFileManager minionGeneralPillarFileManager = - new MinionPillarFileManager(new MinionGeneralPillarGenerator()); /** * {@inheritDoc} @@ -55,8 +49,7 @@ public void setUp() throws Exception { KickstartDataTest.setupTestConfiguration(user); tmpPillarRoot = Files.createTempDirectory("pillar"); tmpSaltRoot = Files.createTempDirectory("salt"); - minionGroupMembershipPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); - minionGeneralPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); + MinionPillarManager.INSTANCE.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); SaltStateGeneratorService.INSTANCE.setSuseManagerStatesFilesRoot(tmpSaltRoot .toAbsolutePath()); Files.createDirectory(tmpSaltRoot.resolve(SALT_CONFIG_STATES_DIR)); diff --git a/java/code/src/com/redhat/rhn/testing/JMockBaseTestCaseWithUser.java b/java/code/src/com/redhat/rhn/testing/JMockBaseTestCaseWithUser.java index 94072e064857..0ef65a57bfc8 100644 --- a/java/code/src/com/redhat/rhn/testing/JMockBaseTestCaseWithUser.java +++ b/java/code/src/com/redhat/rhn/testing/JMockBaseTestCaseWithUser.java @@ -14,14 +14,11 @@ */ package com.redhat.rhn.testing; -import com.redhat.rhn.GlobalInstanceHolder; import com.redhat.rhn.domain.kickstart.test.KickstartDataTest; import com.redhat.rhn.domain.user.User; import com.suse.manager.webui.services.SaltStateGeneratorService; -import com.suse.manager.webui.services.pillar.MinionGeneralPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionGroupMembershipPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.commons.io.FileUtils; @@ -38,10 +35,6 @@ public abstract class JMockBaseTestCaseWithUser extends RhnJmockBaseTestCase { protected User user; protected Path tmpPillarRoot; protected Path tmpSaltRoot; - protected MinionPillarFileManager minionGroupMembershipPillarFileManager = - new MinionPillarFileManager(new MinionGroupMembershipPillarGenerator()); - protected MinionPillarFileManager minionGeneralPillarFileManager = - new MinionPillarFileManager(new MinionGeneralPillarGenerator()); /** * {@inheritDoc} @@ -54,13 +47,10 @@ public void setUp() throws Exception { KickstartDataTest.setupTestConfiguration(user); tmpPillarRoot = Files.createTempDirectory("pillar"); tmpSaltRoot = Files.createTempDirectory("salt"); - minionGroupMembershipPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); - minionGeneralPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); + MinionPillarManager.INSTANCE.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); SaltStateGeneratorService.INSTANCE.setSuseManagerStatesFilesRoot(tmpSaltRoot .toAbsolutePath()); Files.createDirectory(tmpSaltRoot.resolve(SALT_CONFIG_STATES_DIR)); - GlobalInstanceHolder.SERVER_GROUP_MANAGER - .setMinionGroupMembershipPillarFileManager(minionGroupMembershipPillarFileManager); } /** diff --git a/java/code/src/com/redhat/rhn/testing/RhnMockStrutsTestCase.java b/java/code/src/com/redhat/rhn/testing/RhnMockStrutsTestCase.java index dff5b4255fa4..74f72e580c9f 100644 --- a/java/code/src/com/redhat/rhn/testing/RhnMockStrutsTestCase.java +++ b/java/code/src/com/redhat/rhn/testing/RhnMockStrutsTestCase.java @@ -23,9 +23,7 @@ import javax.servlet.http.Cookie; import com.suse.manager.webui.services.SaltStateGeneratorService; -import com.suse.manager.webui.services.pillar.MinionGeneralPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionGroupMembershipPillarGenerator; -import com.suse.manager.webui.services.pillar.MinionPillarFileManager; +import com.suse.manager.webui.services.pillar.MinionPillarManager; import org.apache.struts.action.DynaActionForm; import org.hibernate.HibernateException; @@ -54,10 +52,6 @@ public class RhnMockStrutsTestCase extends MockStrutsTestCase { protected User user; - protected MinionPillarFileManager minionGroupMembershipPillarFileManager = - new MinionPillarFileManager(new MinionGroupMembershipPillarGenerator()); - protected MinionPillarFileManager minionGeneralPillarFileManager = - new MinionPillarFileManager(new MinionGeneralPillarGenerator()); /** * {@inheritDoc} @@ -96,8 +90,7 @@ public void setUp() throws Exception { //Set temporary Salt directories for local runs Path tmpPillarRoot = Files.createTempDirectory("pillar"); Path tmpSaltRoot = Files.createTempDirectory("salt"); - minionGroupMembershipPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); - minionGeneralPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); + MinionPillarManager.INSTANCE.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); SaltStateGeneratorService.INSTANCE.setSuseManagerStatesFilesRoot(tmpSaltRoot .toAbsolutePath()); } diff --git a/java/code/src/com/suse/manager/webui/services/pillar/MinionCustomInfoPillarGenerator.java b/java/code/src/com/suse/manager/webui/services/pillar/MinionCustomInfoPillarGenerator.java new file mode 100644 index 000000000000..25db18d37699 --- /dev/null +++ b/java/code/src/com/suse/manager/webui/services/pillar/MinionCustomInfoPillarGenerator.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2021 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.manager.webui.services.pillar; + +import static com.suse.manager.webui.services.SaltConstants.PILLAR_DATA_FILE_EXT; +import static com.suse.manager.webui.services.SaltConstants.PILLAR_DATA_FILE_PREFIX; + +import com.redhat.rhn.domain.server.MinionServer; + +import com.suse.manager.webui.utils.SaltPillar; + +import org.apache.log4j.Logger; + +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Class for generating minion pillar data containing CustomInfo information of minions + */ +public class MinionCustomInfoPillarGenerator implements MinionPillarGenerator { + + /** Logger */ + private static final Logger LOG = Logger.getLogger(MinionCustomInfoPillarGenerator.class); + + public static final MinionCustomInfoPillarGenerator INSTANCE = new MinionCustomInfoPillarGenerator(); + + /** + * Generates pillar data containing CustomInfo information of the passed minion + * @param minion the minion server + * @return the SaltPillar containing the pillar data + */ + @Override + public Optional generatePillarData(MinionServer minion) { + if (minion.getCustomDataValues().isEmpty()) { + return Optional.empty(); + } + SaltPillar pillar = new SaltPillar(); + pillar.add("custom_info", minion.getCustomDataValues().stream() + .collect(Collectors.toMap(a -> a.getKey().getLabel(), a -> a.getValue()))); + return Optional.of(pillar); + } + + @Override + public String getFilename(String minionId) { + return PILLAR_DATA_FILE_PREFIX + "_" + minionId + "_custom_info." + PILLAR_DATA_FILE_EXT; + } + +} diff --git a/java/code/src/com/suse/manager/webui/services/pillar/MinionGeneralPillarGenerator.java b/java/code/src/com/suse/manager/webui/services/pillar/MinionGeneralPillarGenerator.java index f9a772382266..c54af7074e9f 100644 --- a/java/code/src/com/suse/manager/webui/services/pillar/MinionGeneralPillarGenerator.java +++ b/java/code/src/com/suse/manager/webui/services/pillar/MinionGeneralPillarGenerator.java @@ -86,6 +86,7 @@ public Optional generatePillarData(MinionServer minion) { if (!beaconConfig.isEmpty()) { pillar.add("beacons", beaconConfig); } + return Optional.of(pillar); } diff --git a/java/code/src/com/suse/manager/webui/services/pillar/MinionPillarManager.java b/java/code/src/com/suse/manager/webui/services/pillar/MinionPillarManager.java index 41a539cbbcc9..449b66e82273 100644 --- a/java/code/src/com/suse/manager/webui/services/pillar/MinionPillarManager.java +++ b/java/code/src/com/suse/manager/webui/services/pillar/MinionPillarManager.java @@ -21,32 +21,51 @@ import org.apache.log4j.Logger; -import java.util.Arrays; +import java.nio.file.Path; import java.util.Collection; import java.util.Collections; -import java.util.List; /** * Manager class for generating or removing minion pillar files. */ public class MinionPillarManager { + public enum PillarSubset { + GENERAL, + GROUP_MEMBERSHIP, + VIRTUALIZATION, + CUSTOM_INFO + }; + /** Logger */ private static final Logger LOG = Logger.getLogger(MinionPillarManager.class); public static final MinionPillarManager INSTANCE = new MinionPillarManager( - Arrays.asList(new MinionPillarFileManager(MinionGeneralPillarGenerator.INSTANCE), + new MinionPillarFileManager(MinionGeneralPillarGenerator.INSTANCE), new MinionPillarFileManager(MinionGroupMembershipPillarGenerator.INSTANCE), - new MinionPillarFileManager(MinionVirtualizationPillarGenerator.INSTANCE))); + new MinionPillarFileManager(MinionVirtualizationPillarGenerator.INSTANCE), + new MinionPillarFileManager(MinionCustomInfoPillarGenerator.INSTANCE)); - private List pillarFileManagers; + private MinionPillarFileManager generalPillarFileManager; + private MinionPillarFileManager groupMembershipPillarFileManager; + private MinionPillarFileManager virtualizationPillarFileManager; + private MinionPillarFileManager customInfoPillarFileManager; /** * Constructor for MinionPillarManager - * @param pillarFileManagersIn a list of minion pillar file managers + * @param generalPillarFileManagerIn general pillar file manager + * @param groupMembershipPillarFileManagerIn group membership pillar file manager + * @param virtualizationPillarFileManagerIn virtualization pillar file manager + * @param customInfoPillarFileManagerIn custom info pillar file manager */ - public MinionPillarManager(List pillarFileManagersIn) { - this.pillarFileManagers = pillarFileManagersIn; + public MinionPillarManager(MinionPillarFileManager generalPillarFileManagerIn, + MinionPillarFileManager groupMembershipPillarFileManagerIn, + MinionPillarFileManager virtualizationPillarFileManagerIn, + MinionPillarFileManager customInfoPillarFileManagerIn) { + this.generalPillarFileManager = generalPillarFileManagerIn; + this.groupMembershipPillarFileManager = groupMembershipPillarFileManagerIn; + this.virtualizationPillarFileManager = virtualizationPillarFileManagerIn; + this.customInfoPillarFileManager = customInfoPillarFileManagerIn; } /** @@ -57,6 +76,37 @@ public void generatePillar(MinionServer minion) { generatePillar(minion, true, Collections.emptySet()); } + /** + * Generates specific pillar for the passed minion + * @param minion the minion server + * @param refreshAccessTokens if access tokens should be refreshed first + * @param subsets subsets of pillar, that should be generated + */ + public void generatePillar(MinionServer minion, boolean refreshAccessTokens, + PillarSubset... subsets) { + if (refreshAccessTokens) { + AccessTokenFactory.refreshTokens(minion, Collections.emptySet()); + } + for (PillarSubset subset : subsets) { + switch (subset) { + case GENERAL: + generalPillarFileManager.updatePillarFile(minion); + break; + case GROUP_MEMBERSHIP: + groupMembershipPillarFileManager.updatePillarFile(minion); + break; + case VIRTUALIZATION: + virtualizationPillarFileManager.updatePillarFile(minion); + break; + case CUSTOM_INFO: + customInfoPillarFileManager.updatePillarFile(minion); + break; + default: + throw new RuntimeException("unreachable"); + } + } + } + /** * Generates specific pillar for the passed minion * @param minion the minion server @@ -70,7 +120,10 @@ public void generatePillar(MinionServer minion, boolean refreshAccessTokens, if (refreshAccessTokens) { AccessTokenFactory.refreshTokens(minion, tokensToActivate); } - this.pillarFileManagers.stream().forEach(m -> m.updatePillarFile(minion)); + generalPillarFileManager.updatePillarFile(minion); + groupMembershipPillarFileManager.updatePillarFile(minion); + virtualizationPillarFileManager.updatePillarFile(minion); + customInfoPillarFileManager.updatePillarFile(minion); } /** @@ -78,7 +131,20 @@ public void generatePillar(MinionServer minion, boolean refreshAccessTokens, * @param minionId the minion Id */ public void removePillar(String minionId) { - this.pillarFileManagers.stream().forEach(m -> m.removePillarFile(minionId)); + generalPillarFileManager.removePillarFile(minionId); + groupMembershipPillarFileManager.removePillarFile(minionId); + virtualizationPillarFileManager.removePillarFile(minionId); + customInfoPillarFileManager.removePillarFile(minionId); + } + + /** + * @param pillarDataPathIn the root path where pillar files are generated + */ + public void setPillarDataPath(Path pillarDataPathIn) { + generalPillarFileManager.setPillarDataPath(pillarDataPathIn); + groupMembershipPillarFileManager.setPillarDataPath(pillarDataPathIn); + virtualizationPillarFileManager.setPillarDataPath(pillarDataPathIn); + customInfoPillarFileManager.setPillarDataPath(pillarDataPathIn); } } diff --git a/java/code/src/com/suse/manager/webui/services/pillar/test/MinionGroupMembershipPillarGeneratorTest.java b/java/code/src/com/suse/manager/webui/services/pillar/test/MinionGroupMembershipPillarGeneratorTest.java index 2d53bd217188..679ef8f45d9d 100644 --- a/java/code/src/com/suse/manager/webui/services/pillar/test/MinionGroupMembershipPillarGeneratorTest.java +++ b/java/code/src/com/suse/manager/webui/services/pillar/test/MinionGroupMembershipPillarGeneratorTest.java @@ -23,6 +23,9 @@ import com.redhat.rhn.domain.server.test.ServerGroupTest; import com.redhat.rhn.testing.BaseTestCaseWithUser; import com.redhat.rhn.testing.TestUtils; +import com.suse.manager.webui.services.pillar.MinionGroupMembershipPillarGenerator; +import com.suse.manager.webui.services.pillar.MinionPillarFileManager; + import org.apache.commons.codec.digest.DigestUtils; import org.yaml.snakeyaml.Yaml; @@ -41,9 +44,13 @@ */ public class MinionGroupMembershipPillarGeneratorTest extends BaseTestCaseWithUser { + protected MinionPillarFileManager minionGroupMembershipPillarFileManager = + new MinionPillarFileManager(new MinionGroupMembershipPillarGenerator()); + @Override public void setUp() throws Exception { super.setUp(); + minionGroupMembershipPillarFileManager.setPillarDataPath(tmpPillarRoot.toAbsolutePath()); Config.get().setString("server.secret_key", DigestUtils.sha256Hex(TestUtils.randomString())); } diff --git a/java/code/src/com/suse/manager/webui/services/pillar/test/MinionPillarManagerTest.java b/java/code/src/com/suse/manager/webui/services/pillar/test/MinionPillarManagerTest.java index e6a93ac157a1..292136fbbe79 100644 --- a/java/code/src/com/suse/manager/webui/services/pillar/test/MinionPillarManagerTest.java +++ b/java/code/src/com/suse/manager/webui/services/pillar/test/MinionPillarManagerTest.java @@ -49,15 +49,11 @@ */ public class MinionPillarManagerTest extends BaseTestCaseWithUser { - protected MinionPillarManager minionPillarManager; - @Override public void setUp() throws Exception { super.setUp(); Config.get().setString("server.secret_key", DigestUtils.sha256Hex(TestUtils.randomString())); - minionPillarManager = new MinionPillarManager( - Arrays.asList(this.minionGeneralPillarFileManager, this.minionGroupMembershipPillarFileManager)); } public void testGeneratePillarForServer() throws Exception { @@ -75,7 +71,7 @@ public void testGeneratePillarForServer() throws Exception { minion.addChannel(channel2); ServerFactory.save(minion); - minionPillarManager.generatePillar(minion); + MinionPillarManager.INSTANCE.generatePillar(minion); Path filePath = tmpPillarRoot.resolve( PILLAR_DATA_FILE_PREFIX + "_" + @@ -143,7 +139,7 @@ public void testGeneratePillarForServerGPGCheckOn() throws Exception { minion.addChannel(channel1); ServerFactory.save(minion); - minionPillarManager.generatePillar(minion); + MinionPillarManager.INSTANCE.generatePillar(minion); Path filePath = tmpPillarRoot .resolve(PILLAR_DATA_FILE_PREFIX + "_" + minion.getMinionId() + "." + PILLAR_DATA_FILE_EXT); @@ -172,7 +168,7 @@ public void testGeneratePillarForServerGPGCheckOff() throws Exception { minion.addChannel(channel1); ServerFactory.save(minion); - minionPillarManager.generatePillar(minion); + MinionPillarManager.INSTANCE.generatePillar(minion); Path filePath = tmpPillarRoot.resolve( PILLAR_DATA_FILE_PREFIX + "_" + @@ -228,7 +224,7 @@ public void testGeneratePillarForProxyServer() throws Exception { HibernateFactory.getSession().flush(); HibernateFactory.getSession().refresh(minion); - minionPillarManager.generatePillar(minion); + MinionPillarManager.INSTANCE.generatePillar(minion); Path filePath = tmpPillarRoot.resolve( PILLAR_DATA_FILE_PREFIX + "_" + diff --git a/java/spacewalk-java.changes b/java/spacewalk-java.changes index 42502fa08558..d1ff8c041437 100644 --- a/java/spacewalk-java.changes +++ b/java/spacewalk-java.changes @@ -1,3 +1,4 @@ +- Provide Custom Info as Pillar data - remove deprecated xmlrpc functions - Only update the kickstart path in cobbler if necessary (bsc#1175216) - enhance config channel API with list assigned groups diff --git a/susemanager-utils/susemanager-sls/modules/pillar/suma_minion.py b/susemanager-utils/susemanager-sls/modules/pillar/suma_minion.py index f087e49d09e0..d28334044e99 100644 --- a/susemanager-utils/susemanager-sls/modules/pillar/suma_minion.py +++ b/susemanager-utils/susemanager-sls/modules/pillar/suma_minion.py @@ -47,7 +47,7 @@ ] MINION_PILLAR_FILES_PREFIX = "pillar_{minion_id}" -MINION_PILLAR_FILES_SUFFIXES = [".yml", "_group_memberships.yml", "_virtualization.yml"] +MINION_PILLAR_FILES_SUFFIXES = [".yml", "_group_memberships.yml", "_virtualization.yml", "_custom_info.yml"] CONFIG_FILE = '/etc/rhn/rhn.conf' diff --git a/susemanager-utils/susemanager-sls/susemanager-sls.changes b/susemanager-utils/susemanager-sls/susemanager-sls.changes index 4b2e3f1c2c35..4dfdec066a1f 100644 --- a/susemanager-utils/susemanager-sls/susemanager-sls.changes +++ b/susemanager-utils/susemanager-sls/susemanager-sls.changes @@ -1,3 +1,4 @@ +- Provide Custom Info as Pillar data - Add support for Amazon Linux 2 - add allow vendor change option to pathing via salt - Prevent useless package list refresh actions on zypper minions (bsc#1183661)