Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,31 @@

import com.cloud.utils.component.Manager;
import org.apache.cloudstack.api.command.user.consoleproxy.ConsoleEndpoint;
import org.apache.cloudstack.framework.config.ConfigKey;

public interface ConsoleAccessManager extends Manager {

ConfigKey<Boolean> ConsoleSessionCleanupEnabled = new ConfigKey<>("Advanced", Boolean.class,
"console.session.cleanup.enabled",
"true",
"Enables/disables the console session cleanup thread.",
true,
Comment thread
nvazquez marked this conversation as resolved.
Outdated
ConfigKey.Scope.Global);
Comment thread
nvazquez marked this conversation as resolved.
Outdated

ConfigKey<Integer> ConsoleSessionCleanupRetentionDays = new ConfigKey<>("Advanced", Integer.class,
"console.session.cleanup.retention.days",
Comment thread
nvazquez marked this conversation as resolved.
Outdated
"7",
"Determines the days to keep removed console session records before expunging them",
true,
ConfigKey.Scope.Global);

ConfigKey<Integer> ConsoleSessionCleanupInterval = new ConfigKey<>("Advanced", Integer.class,
"console.session.cleanup.interval",
"180",
"Determines how long (in hours) to wait before actually expunging destroyed console session records",
true,
ConfigKey.Scope.Global);

ConsoleEndpoint generateConsoleEndpoint(Long vmId, String extraSecurityToken, String clientAddress);

boolean isSessionAllowed(String sessionUuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@
import com.cloud.vm.ConsoleSessionVO;
import com.cloud.utils.db.GenericDao;

import java.util.Date;
import java.util.List;

public interface ConsoleSessionDao extends GenericDao<ConsoleSessionVO, Long> {

void removeSession(String sessionUuid);

boolean isSessionAllowed(String sessionUuid);

List<ConsoleSessionVO> listRemovedSessionsOlderThanDate(Date date);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,24 @@

package com.cloud.vm.dao;

import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.ConsoleSessionVO;
import com.cloud.utils.db.GenericDaoBase;

import java.util.Date;
import java.util.List;

public class ConsoleSessionDaoImpl extends GenericDaoBase<ConsoleSessionVO, Long> implements ConsoleSessionDao {

private final SearchBuilder<ConsoleSessionVO> SearchByRemovedDate;

public ConsoleSessionDaoImpl() {
SearchByRemovedDate = createSearchBuilder();
SearchByRemovedDate.and("removed", SearchByRemovedDate.entity().getRemoved(), SearchCriteria.Op.NNULL);
Comment thread
nvazquez marked this conversation as resolved.
Outdated
SearchByRemovedDate.and("removed", SearchByRemovedDate.entity().getRemoved(), SearchCriteria.Op.LTEQ);
}

@Override
public void removeSession(String sessionUuid) {
ConsoleSessionVO session = findByUuid(sessionUuid);
Expand All @@ -34,4 +47,11 @@ public void removeSession(String sessionUuid) {
public boolean isSessionAllowed(String sessionUuid) {
return findByUuid(sessionUuid) != null;
}

@Override
public List<ConsoleSessionVO> listRemovedSessionsOlderThanDate(Date date) {
SearchCriteria<ConsoleSessionVO> searchCriteria = SearchByRemovedDate.create();
searchCriteria.setParameters("removed", date);
return listBy(searchCriteria);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.ConsoleSessionVO;
import com.cloud.vm.UserVmDetailVO;
Expand All @@ -50,8 +52,11 @@
import org.apache.cloudstack.api.command.user.consoleproxy.ConsoleEndpoint;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.security.keys.KeysManager;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
Expand All @@ -63,9 +68,13 @@

import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ConsoleAccessManagerImpl extends ManagerBase implements ConsoleAccessManager {
Comment thread
nvazquez marked this conversation as resolved.

Expand All @@ -88,6 +97,8 @@ public class ConsoleAccessManagerImpl extends ManagerBase implements ConsoleAcce
@Inject
private ConsoleSessionDao consoleSessionDao;

private ScheduledExecutorService executorService = null;

private static KeysManager secretKeysManager;
private final Gson gson = new GsonBuilder().create();

Expand All @@ -100,9 +111,53 @@ public class ConsoleAccessManagerImpl extends ManagerBase implements ConsoleAcce
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
ConsoleAccessManagerImpl.secretKeysManager = keysManager;
executorService = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ConsoleSession-Scavenger"));
return super.configure(name, params);
}

@Override
public boolean start() {
Integer consoleCleanupInterval = ConsoleAccessManager.ConsoleSessionCleanupInterval.value();
Comment thread
nvazquez marked this conversation as resolved.
Outdated
Boolean consoleCleanupEnabled = ConsoleAccessManager.ConsoleSessionCleanupEnabled.value();
if (BooleanUtils.isTrue(consoleCleanupEnabled)) {
Comment thread
nvazquez marked this conversation as resolved.
Outdated
s_logger.info(String.format("The ConsoleSessionCleanupTask will run every %s hours", consoleCleanupInterval));
executorService.scheduleWithFixedDelay(new ConsoleSessionCleanupTask(), consoleCleanupInterval, consoleCleanupInterval, TimeUnit.HOURS);
}
return true;
}

public class ConsoleSessionCleanupTask extends ManagedContextRunnable {
@Override
protected void runInContext() {
final GlobalLock gcLock = GlobalLock.getInternLock("ConsoleSession.Cleanup.Lock");
try {
if (gcLock.lock(3)) {
try {
reallyRun();
} finally {
gcLock.unlock();
}
}
} finally {
gcLock.releaseRef();
}
}

private void reallyRun() {
s_logger.info("Starting ConsoleSessionCleanupTask...");
Integer retentionDays = ConsoleAccessManager.ConsoleSessionCleanupRetentionDays.value();
Date date = GregorianCalendar.getInstance().getTime();
Comment thread
nvazquez marked this conversation as resolved.
Outdated
Date dateBefore = new Date(date.getTime() - retentionDays * 24 * 3600 * 1000);
List<ConsoleSessionVO> sessionsToExpunge = consoleSessionDao.listRemovedSessionsOlderThanDate(dateBefore);
if (CollectionUtils.isNotEmpty(sessionsToExpunge)) {
Comment thread
nvazquez marked this conversation as resolved.
Outdated
s_logger.info(String.format("Expunging %s removed console session records"));
Comment thread
nvazquez marked this conversation as resolved.
Outdated
for (ConsoleSessionVO sessionVO : sessionsToExpunge) {
consoleSessionDao.expunge(sessionVO.getId());
}
}
}
}

@Override
public ConsoleEndpoint generateConsoleEndpoint(Long vmId, String extraSecurityToken, String clientAddress) {
try {
Expand Down