/**
* Copyright (c) 2009--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.
*/
package com.redhat.rhn.manager.org;
import com.redhat.rhn.common.security.PermissionException;
import com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.org.OrgFactory;
import com.redhat.rhn.domain.org.SystemMigration;
import com.redhat.rhn.domain.org.SystemMigrationFactory;
import com.redhat.rhn.domain.role.RoleFactory;
import com.redhat.rhn.domain.server.ManagedServerGroup;
import com.redhat.rhn.domain.server.Server;
import com.redhat.rhn.domain.server.ServerFactory;
import com.redhat.rhn.domain.server.ServerHistoryEvent;
import com.redhat.rhn.domain.server.ServerSnapshot;
import com.redhat.rhn.domain.token.Token;
import com.redhat.rhn.domain.token.TokenFactory;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.domain.user.UserFactory;
import com.redhat.rhn.manager.BaseManager;
import com.redhat.rhn.manager.errata.cache.ErrataCacheManager;
import com.redhat.rhn.manager.system.ServerGroupManager;
import com.redhat.rhn.manager.system.SystemManager;
import com.redhat.rhn.manager.system.UpdateChildChannelsCommand;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* MigrationManager
*
* Handles the migration of systems from one organization to another.
*
* @version $Rev$
*/
public class MigrationManager extends BaseManager {
/**
* Migrate a set of servers to the organization specified
* @param user Org admin that is performing the migration
* @param toOrg The destination org
* @param servers List of servers to be migrated
* @return the list of server ids successfully migrated.
*/
public static List<Long> migrateServers(User user, Org toOrg, List<Server> servers) {
List<Long> serversMigrated = new ArrayList<Long>();
for (Server server : servers) {
Org fromOrg = server.getOrg();
// Update the server to ignore entitlement checking... This is needed to ensure
// that things such as configuration files are moved with the system, even if
// the system currently has provisioning entitlements removed.
server.setIgnoreEntitlementsForMigration(Boolean.TRUE);
MigrationManager.removeOrgRelationships(user, server);
MigrationManager.updateAdminRelationships(fromOrg, toOrg, server);
MigrationManager.moveServerToOrg(toOrg, server);
serversMigrated.add(server.getId());
OrgFactory.save(toOrg);
OrgFactory.save(fromOrg);
ServerFactory.save(server);
if (user.getOrg().equals(toOrg)) {
server.setCreator(user);
}
else {
server.setCreator(UserFactory.findRandomOrgAdmin(toOrg));
}
// update server history to record the migration.
ServerHistoryEvent event = new ServerHistoryEvent();
event.setCreated(new Date());
event.setServer(server);
event.setSummary("System migration");
String details = "From organization: " + fromOrg.getName();
details += ", To organization: " + toOrg.getName();
event.setDetails(details);
server.getHistory().add(event);
SystemMigration migration = SystemMigrationFactory.createSystemMigration();
migration.setToOrg(toOrg);
migration.setFromOrg(fromOrg);
migration.setServer(server);
migration.setMigrated(new Date());
SystemMigrationFactory.save(migration);
}
return serversMigrated;
}
/**
* Remove a server's relationships with it's current org.
*
* Used to clean the servers associations in the database in preparation for migration
* before the server profile is moved to the migration queue.
*
* @param user Org admin performing the migration.
* @param server Server to be migrated.
*/
public static void removeOrgRelationships(User user, Server server) {
if (!user.hasRole(RoleFactory.ORG_ADMIN)) {
throw new PermissionException(RoleFactory.ORG_ADMIN);
}
// Unsubscribe from all channels to change channel entitlements
UpdateChildChannelsCommand cmd = new UpdateChildChannelsCommand(user, server,
new ArrayList());
cmd.store();
SystemManager.unsubscribeServerFromChannel(server, server.getBaseChannel());
// Remove from all system groups:
ServerGroupManager manager = ServerGroupManager.getInstance();
for (ManagedServerGroup group : server.getManagedGroups()) {
List<Server> tempList = new LinkedList<Server>();
tempList.add(server);
manager.removeServers(group, tempList);
}
// Remove custom data values (aka System->CustomInfo)
ServerFactory.removeCustomDataValues(server);
// Remove existing config channels
if (server.getConfigChannelCount() > 0) {
server.getConfigChannels().clear();
}
// If the server has a reactivation keys, remove them...
// They will not be valid once the server is in the new org.
List<Token> tokenList = TokenFactory.listByServer(server);
for (Token token : tokenList) {
TokenFactory.removeToken(token);
}
// Remove the errata and package cache
ErrataCacheManager.deleteNeededErrataCache(server.getId());
ErrataCacheManager.deleteNeededPackageCache(server.getId());
// Remove snapshots
List<ServerSnapshot> snapshots = ServerFactory.listSnapshots(
server.getOrg(), server, null, null);
for (ServerSnapshot snapshot : snapshots) {
ServerFactory.deleteSnapshot(snapshot);
}
SystemManager.removeAllServerEntitlements(server.getId());
}
/**
* Update the org admin to server relationships in the originating and destination
* orgs.
*
* @param fromOrg originating org where the server currently exists
* @param toOrg destination org where the server will be migrated to
* @param server Server to be migrated.
*/
public static void updateAdminRelationships(Org fromOrg, Org toOrg, Server server) {
// TODO: In some scenarios this appears to be somewhat slow, for an org with
// around a thousand org admins and a dozen or so servers, this can take about a
// minute to run. Probably a much more efficient way to do this. (i.e. delete
// from rhnUserServerPerms where server_id = blah. Add a huge number of servers to
// the mix and it could take quite some time.
for (User admin : fromOrg.getActiveOrgAdmins()) {
admin.removeServer(server);
UserFactory.save(admin);
}
// add the server to all org admins in the destination org
for (User admin : toOrg.getActiveOrgAdmins()) {
admin.addServer(server);
UserFactory.save(admin);
}
}
/**
* Move the server to the destination org.
*
* @param toOrg destination org where the server will be migrated to
* @param server Server to be migrated.
*/
public static void moveServerToOrg(Org toOrg, Server server) {
// if the server has any "Locally-Managed" config files associated with it, then
// a config channel was created for them... that channel needs to be moved to
// the new org...
if (server.getLocalOverrideNoCreate() != null) {
server.getLocalOverrideNoCreate().setOrg(toOrg);
}
// if the server has any "Local Sandbox" config files associated with it, then
// a config channel was created for them... that channel needs to be moved to
// the new org...
if (server.getSandboxOverrideNoCreate() != null) {
server.getSandboxOverrideNoCreate().setOrg(toOrg);
}
// Move the server
server.setOrg(toOrg);
}
}