/**
* Copyright (c) 2009--2014 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.
*/
package com.redhat.rhn.frontend.xmlrpc.system.config.test;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.validator.ValidatorException;
import com.redhat.rhn.domain.action.ActionFactory;
import com.redhat.rhn.domain.action.config.ConfigAction;
import com.redhat.rhn.domain.action.config.ConfigRevisionAction;
import com.redhat.rhn.domain.config.ConfigChannel;
import com.redhat.rhn.domain.config.ConfigChannelType;
import com.redhat.rhn.domain.config.ConfigFile;
import com.redhat.rhn.domain.config.ConfigFileState;
import com.redhat.rhn.domain.config.ConfigFileType;
import com.redhat.rhn.domain.config.ConfigRevision;
import com.redhat.rhn.domain.config.ConfigurationFactory;
import com.redhat.rhn.domain.server.Server;
import com.redhat.rhn.domain.server.ServerFactory;
import com.redhat.rhn.domain.server.test.ServerFactoryTest;
import com.redhat.rhn.frontend.dto.ConfigFileNameDto;
import com.redhat.rhn.frontend.dto.ScheduledAction;
import com.redhat.rhn.frontend.xmlrpc.serializer.ConfigRevisionSerializer;
import com.redhat.rhn.frontend.xmlrpc.system.config.ServerConfigHandler;
import com.redhat.rhn.frontend.xmlrpc.test.BaseHandlerTestCase;
import com.redhat.rhn.manager.action.ActionManager;
import com.redhat.rhn.manager.system.SystemManager;
import com.redhat.rhn.manager.system.test.SystemManagerTest;
import com.redhat.rhn.testing.ConfigTestUtils;
import com.redhat.rhn.testing.TestUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* SystemConfigHandlerTest
*/
public class ServerConfigHandlerTest extends BaseHandlerTestCase {
private ServerConfigHandler handler = new ServerConfigHandler();
public void testDeployConfiguration() throws Exception {
// Create global config channels
ConfigChannel gcc1 = ConfigTestUtils.createConfigChannel(admin.getOrg(),
ConfigChannelType.global());
ConfigChannel gcc2 = ConfigTestUtils.createConfigChannel(admin.getOrg(),
ConfigChannelType.global());
Long ver = new Long(2);
// gcc1 only
Server srv1 = ServerFactoryTest.createTestServer(regular, true);
srv1.subscribe(gcc1);
srv1.subscribe(gcc2);
ServerFactory.save(srv1);
Set <ConfigRevision> revisions = new HashSet<ConfigRevision>();
ConfigFile g1f1 = gcc1.createConfigFile(
ConfigFileState.normal(), "/etc/foo1");
revisions.add(ConfigTestUtils.createConfigRevision(g1f1));
ConfigurationFactory.commit(gcc1);
ConfigFile g1f2 = gcc1.createConfigFile(
ConfigFileState.normal(), "/etc/foo2");
revisions.add(ConfigTestUtils.createConfigRevision(g1f2));
ConfigurationFactory.commit(gcc2);
ConfigFile g2f2 = gcc2.createConfigFile(
ConfigFileState.normal(), "/etc/foo4");
revisions.add(ConfigTestUtils.createConfigRevision(g2f2));
ConfigurationFactory.commit(gcc2);
ConfigFile g2f3 = gcc2.createConfigFile(
ConfigFileState.normal(), "/etc/foo3");
revisions.add(ConfigTestUtils.createConfigRevision(g2f3));
ConfigurationFactory.commit(gcc2);
// System 1 - both g1f1 and g1f2 should deploy here
List<Number> systems = new ArrayList<Number>();
systems.add(srv1.getId());
Date date = new Date();
try {
// validate that system must have config deployment capability
// in order to deploy config files... (e.g. rhncfg* pkgs installed)
handler.deployAll(regular, systems, date);
fail("Shouldn't be permitted to deploy without config deploy capability.");
}
catch (Exception e) {
// Success
}
SystemManagerTest.giveCapability(srv1.getId(),
SystemManager.CAP_CONFIGFILES_DEPLOY, ver);
handler.deployAll(regular, systems, date);
DataResult<ScheduledAction> actions = ActionManager.
recentlyScheduledActions(regular, null, 1);
ConfigAction ca = null;
for (ScheduledAction action : actions) {
if (ActionFactory.TYPE_CONFIGFILES_DEPLOY.getName().
equals(action.getTypeName())) {
ca = (ConfigAction)ActionManager.lookupAction(regular,
action.getId().longValue());
}
}
assertNotNull(ca);
assertEquals(revisions.size(), ca.getConfigRevisionActions().size());
for (ConfigRevisionAction cra : ca.getConfigRevisionActions()) {
assertTrue(revisions.contains(cra.getConfigRevision()));
}
}
public void testConfigChannels() throws Exception {
// Create global config channels
ConfigChannel gcc1 = ConfigTestUtils.createConfigChannel(admin.getOrg(),
ConfigChannelType.global());
ConfigChannel gcc2 = ConfigTestUtils.createConfigChannel(admin.getOrg(),
ConfigChannelType.global());
Server srv1 = ServerFactoryTest.createTestServer(regular, true);
List<Number> serverIds = new LinkedList<Number>();
serverIds.add(srv1.getId());
List <ConfigChannel> channels = new LinkedList<ConfigChannel>();
channels.add(gcc1);
channels.add(gcc2);
List <String> channelLabels = new LinkedList<String>();
for (ConfigChannel cc : channels) {
channelLabels.add(cc.getLabel());
}
handler.setChannels(admin, serverIds, channelLabels);
List<ConfigChannel> actual = handler.listChannels(regular,
srv1.getId().intValue());
assertEquals(channels, actual);
handler.removeChannels(admin, serverIds,
channelLabels.subList(0, 1));
actual = handler.listChannels(regular,
srv1.getId().intValue());
assertEquals(channels.subList(1, channels.size()), actual);
//test add channels
handler.addChannels(admin, serverIds, channelLabels.subList(0, 1), true);
actual = handler.listChannels(regular,
srv1.getId().intValue());
assertEquals(channels, actual);
assertEquals(1, handler.removeChannels(admin, serverIds,
channelLabels.subList(1, channelLabels.size())));
assertEquals(1,
handler.addChannels(admin, serverIds, channelLabels.subList(1,
channelLabels.size()), false));
actual = handler.listChannels(regular, srv1.getId().intValue());
assertEquals(channels, actual);
}
private ConfigRevision createRevision(String path, String contents,
String group, String owner,
String perms, boolean isDir,
Server server, boolean commitToLocal, String selinuxCtx)
throws ValidatorException {
Map <String, Object> data = new HashMap<String, Object>();
data.put(ConfigRevisionSerializer.GROUP, group);
data.put(ConfigRevisionSerializer.OWNER, owner);
data.put(ConfigRevisionSerializer.PERMISSIONS, perms);
data.put(ConfigRevisionSerializer.SELINUX_CTX, selinuxCtx);
String start = "#@";
String end = "@#";
if (!isDir) {
data.put(ConfigRevisionSerializer.CONTENTS, contents);
data.put(ConfigRevisionSerializer.MACRO_START, start);
data.put(ConfigRevisionSerializer.MACRO_END, end);
}
ConfigRevision rev = handler.createOrUpdatePath(
admin, server.getId().intValue(),
path, isDir, data, commitToLocal);
ConfigChannel cc = commitToLocal ? server.getLocalOverride() :
server.getSandboxOverride();
assertRev(rev, path, contents, group, owner, perms, isDir, cc, start, end,
selinuxCtx);
assertRevNotChanged(rev, server, commitToLocal);
return rev;
}
private ConfigRevision createSymlinkRevision(String path, String targetPath,
Server server, boolean commitToLocal, String selinuxCtx)
throws ValidatorException {
Map <String, Object> data = new HashMap<String, Object>();
data.put(ConfigRevisionSerializer.TARGET_PATH, targetPath);
data.put(ConfigRevisionSerializer.SELINUX_CTX, selinuxCtx);
ConfigRevision rev = handler.createOrUpdateSymlink(admin,
server.getId().intValue(), path, data, commitToLocal);
ConfigChannel cc = commitToLocal ? server.getLocalOverride() :
server.getSandboxOverride();
assertRevNotChanged(rev, server, commitToLocal);
assertEquals(path, rev.getConfigFile().getConfigFileName().getPath());
assertEquals(ConfigFileType.symlink(), rev.getConfigFileType());
assertEquals(targetPath, rev.getConfigInfo().getTargetFileName().getPath());
assertEquals(selinuxCtx, rev.getConfigInfo().getSelinuxCtx());
assertEquals(cc, rev.getConfigFile().getConfigChannel());
assertRevNotChanged(rev, server, commitToLocal);
return rev;
}
private void assertRev(ConfigRevision rev, String path, String contents,
String group, String owner,
String perms, boolean isDir, ConfigChannel cc,
String macroStart, String macroEnd, String selinuxCtx) {
assertEquals(path, rev.getConfigFile().getConfigFileName().getPath());
assertEquals(group, rev.getConfigInfo().getGroupname());
assertEquals(owner, rev.getConfigInfo().getUsername());
assertEquals(perms, String.valueOf(rev.getConfigInfo().getFilemode()));
assertEquals(selinuxCtx, rev.getConfigInfo().getSelinuxCtx());
if (isDir) {
assertEquals(ConfigFileType.dir(), rev.getConfigFileType());
}
else {
if (ConfigFileType.file().equals(rev.getConfigFileType())) {
assertEquals(contents, rev.getConfigContent().getContentsString());
assertEquals(macroStart, rev.getConfigContent().getDelimStart());
assertEquals(macroEnd, rev.getConfigContent().getDelimEnd());
}
}
assertEquals(cc,
rev.getConfigFile().getConfigChannel());
}
private void assertRev(ConfigRevision rev, String path, Server server,
boolean lookLocal) {
List<String> paths = new ArrayList<String>(1);
paths.add(path);
assertTrue(rev.matches(handler.lookupFileInfo(admin, server.getId().intValue(),
paths, lookLocal).get(0)));
}
public void testLookupFileInfoNoData() throws Exception {
Server srv1 = ServerFactoryTest.createTestServer(regular, true);
List<String> paths = new LinkedList<String>();
paths.add("/no/such/file.txt");
// Should not throw a NullPointerException (anymore):
handler.lookupFileInfo(admin, new Integer(srv1.getId().intValue()),
paths, true);
}
private void assertRevNotChanged(ConfigRevision rev,
Server server, boolean local) {
assertRev(rev, rev.getConfigFile().getConfigFileName().getPath(),
server, local);
}
public void testAddPath() throws Exception {
Server srv1 = ServerFactoryTest.createTestServer(regular, true);
String path = "/tmp/foo/path" + TestUtils.randomString();
String contents = "HAHAHAHA";
ConfigRevision rev = createRevision(path, contents,
"group" + TestUtils.randomString(),
"owner" + TestUtils.randomString(),
"777",
false, srv1, true, "unconfined_u:object_r:tmp_t");
try {
createRevision(path, contents,
"group" + TestUtils.randomString(),
"owner" + TestUtils.randomString(),
"744",
true, srv1, true, "unconfined_u:object_r:tmp_t");
fail("Can't change the path from file to directory.");
}
catch (Exception e) {
// Can;t change.. Won't allow...
assertRevNotChanged(rev, srv1, true);
}
try {
createRevision(path + TestUtils.randomString() + "/" , contents,
"group" + TestUtils.randomString(),
"owner" + TestUtils.randomString(),
"744",
true, srv1, false, "unconfined_u:object_r:tmp_t");
fail("Validation error on the path.");
}
catch (Exception e) {
// Can;t change.. Won't allow...
assertRevNotChanged(rev, srv1, true);
}
createRevision(path + TestUtils.randomString(), "",
"group" + TestUtils.randomString(),
"owner" + TestUtils.randomString(),
"744",
true, srv1, false, "unconfined_u:object_r:tmp_t");
createSymlinkRevision(path + TestUtils.randomString(),
path + TestUtils.randomString(), srv1, false, "root:root");
}
public void testListFiles() throws Exception {
Server srv1 = ServerFactoryTest.createTestServer(regular, true);
for (int j = 0; j < 2; j++) {
boolean local = j % 2 == 0;
List<String> paths = new LinkedList<String>();
Map<String, ConfigRevision> revisions = new HashMap<String, ConfigRevision>();
setupPathsAndRevisions(srv1, paths, revisions, local);
List<ConfigFileNameDto> files = handler.listFiles(admin,
srv1.getId().intValue(), local);
for (ConfigFileNameDto dto : files) {
assertTrue(revisions.containsKey(dto.getPath()));
ConfigRevision rev = revisions.get(dto.getPath());
assertEquals(rev.getConfigFileType().getLabel(),
dto.getConfigFileType());
assertNotNull(dto.getLastModifiedDate());
}
}
}
/**
* @param srv1 server
* @param paths list holder of paths
* @param revisions list holder of revisions
* @param local is local revision or sandbox
*/
private void setupPathsAndRevisions(Server srv1, List<String> paths,
Map<String, ConfigRevision> revisions, boolean local) {
String path = "/tmp/foo/path/";
for (int i = 0; i < 10; i++) {
boolean isDir = i % 2 == 0;
String newPath = path + TestUtils.randomString();
String contents = isDir ? "" : TestUtils.randomString();
paths.add(newPath);
revisions.put(newPath, createRevision(newPath,
contents,
"group" + TestUtils.randomString(),
"owner" + TestUtils.randomString(),
"744",
isDir, srv1, local,
"unconfined_u:object_r:tmp_t"));
}
}
public void testRemovePaths() throws Exception {
Server srv1 = ServerFactoryTest.createTestServer(regular, true);
for (int i = 0; i < 2; i++) {
boolean isLocal = i % 2 == 0;
List<String> paths = new LinkedList<String>();
Map<String, ConfigRevision> revisions = new HashMap<String, ConfigRevision>();
setupPathsAndRevisions(srv1, paths, revisions, isLocal);
paths.remove(paths.size() - 1);
handler.deleteFiles(admin, srv1.getId().intValue(), paths, isLocal);
List<ConfigFileNameDto> files = handler.listFiles(admin,
srv1.getId().intValue(), isLocal);
assertEquals(1, files.size());
}
}
}