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
Prev Previous commit
Next Next commit
Change upgrade path to 4.19
  • Loading branch information
BryanMLima committed Sep 18, 2023
commit 6112b56c19f23f5617b8ac3cf95e69434a29bdb8
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,18 @@
package com.cloud.upgrade.dao;

import com.cloud.upgrade.SystemVmTemplateRegistration;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
import org.jasypt.exceptions.EncryptionOperationNotPossibleException;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate {
final static Logger LOG = Logger.getLogger(Upgrade41800to41810.class);
private SystemVmTemplateRegistration systemVmTemplateRegistration;

static final String ACCOUNT_DETAILS = "account_details";

static final String DOMAIN_DETAILS = "domain_details";

@Override
public String[] getUpgradableVersionRange() {
return new String[] {"4.18.0.0", "4.18.1.0"};
Expand Down Expand Up @@ -69,7 +58,6 @@ public InputStream[] getPrepareScripts() {
@Override
public void performDataMigration(Connection conn) {
fixForeignKeyNames(conn);
decryptConfigurationValuesFromAccountAndDomainScopesNotInSecureHiddenCategories(conn);
}

@Override
Expand Down Expand Up @@ -123,56 +111,4 @@ private void fixForeignKeyNames(Connection conn) {
DbUpgradeUtils.dropKeysIfExist(conn, "cloud.volumes", keys, false);
DbUpgradeUtils.addForeignKey(conn, "volumes", "passphrase_id","passphrase", "id");
}

protected void decryptConfigurationValuesFromAccountAndDomainScopesNotInSecureHiddenCategories(Connection conn) {
LOG.info("Decrypting global configuration values from the following tables: account_details and domain_details.");

Map<Long, String> accountsMap = getConfigsWithScope(conn, ACCOUNT_DETAILS);
updateConfigValuesWithScope(conn, accountsMap, ACCOUNT_DETAILS);
LOG.info("Successfully decrypted configurations from account_details table.");

Map<Long, String> domainsMap = getConfigsWithScope(conn, DOMAIN_DETAILS);
updateConfigValuesWithScope(conn, domainsMap, DOMAIN_DETAILS);
LOG.info("Successfully decrypted configurations from domain_details table.");
}

protected Map<Long, String> getConfigsWithScope(Connection conn, String table) {
Map<Long, String> configsToBeUpdated = new HashMap<>();
String selectDetails = String.format("SELECT details.id, details.value from cloud.%s details, cloud.configuration c " +
"WHERE details.name = c.name AND c.category NOT IN ('Hidden', 'Secure') AND details.value <> \"\" ORDER BY details.id;", table);

try (PreparedStatement pstmt = conn.prepareStatement(selectDetails)) {
try (ResultSet result = pstmt.executeQuery()) {
while (result.next()) {
configsToBeUpdated.put(result.getLong("id"), result.getString("value"));
}
}
return configsToBeUpdated;
} catch (SQLException e) {
String message = String.format("Unable to retrieve data from table [%s] due to [%s].", table, e.getMessage());
LOG.error(message, e);
throw new CloudRuntimeException(message, e);
}
}

protected void updateConfigValuesWithScope(Connection conn, Map<Long, String> configsToBeUpdated, String table) {
String updateConfigValues = String.format("UPDATE cloud.%s SET value = ? WHERE id = ?;", table);

for (Map.Entry<Long, String> config : configsToBeUpdated.entrySet()) {
try (PreparedStatement pstmt = conn.prepareStatement(updateConfigValues)) {
String decryptedValue = DBEncryptionUtil.decrypt(config.getValue());

pstmt.setString(1, decryptedValue);
pstmt.setLong(2, config.getKey());

LOG.info(String.format("Updating config with ID [%s] to value [%s].", config.getKey(), decryptedValue));
pstmt.executeUpdate();
} catch (SQLException | EncryptionOperationNotPossibleException e) {
String message = String.format("Unable to update config value with ID [%s] on table [%s] due to [%s]. The config value may already be decrypted.",
config.getKey(), table, e);
LOG.error(message);
throw new CloudRuntimeException(message, e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,27 @@
package com.cloud.upgrade.dao;

import com.cloud.upgrade.SystemVmTemplateRegistration;
import com.cloud.utils.crypt.DBEncryptionUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
import org.jasypt.exceptions.EncryptionOperationNotPossibleException;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class Upgrade41810to41900 implements DbUpgrade, DbUpgradeSystemVmTemplate {
final static Logger LOG = Logger.getLogger(Upgrade41810to41900.class);
private SystemVmTemplateRegistration systemVmTemplateRegistration;

private static final String ACCOUNT_DETAILS = "account_details";

private static final String DOMAIN_DETAILS = "domain_details";

@Override
public String[] getUpgradableVersionRange() {
return new String[] {"4.18.1.0", "4.19.0.0"};
Expand Down Expand Up @@ -55,6 +66,7 @@ public InputStream[] getPrepareScripts() {

@Override
public void performDataMigration(Connection conn) {
decryptConfigurationValuesFromAccountAndDomainScopesNotInSecureHiddenCategories(conn);
}

@Override
Expand Down Expand Up @@ -82,4 +94,56 @@ public void updateSystemVmTemplates(Connection conn) {
throw new CloudRuntimeException("Failed to find / register SystemVM template(s)");
}
}

protected void decryptConfigurationValuesFromAccountAndDomainScopesNotInSecureHiddenCategories(Connection conn) {
LOG.info("Decrypting global configuration values from the following tables: account_details and domain_details.");

Map<Long, String> accountsMap = getConfigsWithScope(conn, ACCOUNT_DETAILS);
updateConfigValuesWithScope(conn, accountsMap, ACCOUNT_DETAILS);
LOG.info("Successfully decrypted configurations from account_details table.");

Map<Long, String> domainsMap = getConfigsWithScope(conn, DOMAIN_DETAILS);
updateConfigValuesWithScope(conn, domainsMap, DOMAIN_DETAILS);
LOG.info("Successfully decrypted configurations from domain_details table.");
}

protected Map<Long, String> getConfigsWithScope(Connection conn, String table) {
Map<Long, String> configsToBeUpdated = new HashMap<>();
String selectDetails = String.format("SELECT details.id, details.value from cloud.%s details, cloud.configuration c " +
"WHERE details.name = c.name AND c.category NOT IN ('Hidden', 'Secure') AND details.value <> \"\" ORDER BY details.id;", table);

try (PreparedStatement pstmt = conn.prepareStatement(selectDetails)) {
try (ResultSet result = pstmt.executeQuery()) {
while (result.next()) {
configsToBeUpdated.put(result.getLong("id"), result.getString("value"));
}
}
return configsToBeUpdated;
} catch (SQLException e) {
String message = String.format("Unable to retrieve data from table [%s] due to [%s].", table, e.getMessage());
LOG.error(message, e);
throw new CloudRuntimeException(message, e);
}
}

protected void updateConfigValuesWithScope(Connection conn, Map<Long, String> configsToBeUpdated, String table) {
String updateConfigValues = String.format("UPDATE cloud.%s SET value = ? WHERE id = ?;", table);

for (Map.Entry<Long, String> config : configsToBeUpdated.entrySet()) {
try (PreparedStatement pstmt = conn.prepareStatement(updateConfigValues)) {
String decryptedValue = DBEncryptionUtil.decrypt(config.getValue());

pstmt.setString(1, decryptedValue);
pstmt.setLong(2, config.getKey());

LOG.info(String.format("Updating config with ID [%s] to value [%s].", config.getKey(), decryptedValue));
pstmt.executeUpdate();
} catch (SQLException | EncryptionOperationNotPossibleException e) {
String message = String.format("Unable to update config value with ID [%s] on table [%s] due to [%s]. The config value may already be decrypted.",
config.getKey(), table, e);
LOG.error(message);
throw new CloudRuntimeException(message, e);
}
}
}
}