Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
18 changes: 18 additions & 0 deletions engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.log4j.Logger;

import com.cloud.hypervisor.Hypervisor;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException;

public class Upgrade41000to41100 implements DbUpgrade {
Expand Down Expand Up @@ -65,10 +66,27 @@ public InputStream[] getPrepareScripts() {

@Override
public void performDataMigration(Connection conn) {
checkAndEnableDynamicRoles(conn);
validateUserDataInBase64(conn);
updateSystemVmTemplates(conn);
}

private void checkAndEnableDynamicRoles(final Connection conn) {
final Map<String, String> apiMap = PropertiesUtil.processConfigFile(new String[] { "commands.properties" });
if (apiMap == null || apiMap.isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("No commands.properties file was found, enabling dynamic roles by setting dynamic.apichecker.enabled to true if not already enabled.");
}
try (final PreparedStatement updateStatement = conn.prepareStatement("INSERT INTO cloud.configuration (category, instance, name, default_value, value) VALUES ('Advanced', 'DEFAULT', 'dynamic.apichecker.enabled', 'false', 'true') ON DUPLICATE KEY UPDATE value='true'")) {
updateStatement.executeUpdate();
} catch (SQLException e) {
LOG.error("Failed to set dynamic.apichecker.enabled to true, please run migrate-dynamicroles.py script to manually migrate to dynamic roles.", e);
}
} else {
LOG.warn("Old commands.properties static checker is deprecated, please use migrate-dynamicroles.py to migrate to dynamic roles. Refer http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/accounts.html#using-dynamic-roles");
}
}

private void validateUserDataInBase64(Connection conn) {
try (final PreparedStatement selectStatement = conn.prepareStatement("SELECT `id`, `user_data` FROM `cloud`.`user_vm` WHERE `user_data` IS NOT NULL;");
final ResultSet selectResultSet = selectStatement.executeQuery()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

// This is the default API access checker that grab's the user's account
// based on the account type, access is granted
@Deprecated
public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIChecker {

protected static final Logger LOGGER = Logger.getLogger(StaticRoleBasedAPIAccessChecker.class);
Expand Down
27 changes: 18 additions & 9 deletions scripts/util/migrate-dynamicroles.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ def migrateApiRolePermissions(apis, conn):
if (octetKey[role] & int(apis[api])) > 0:
runSql(conn, "INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), %d, '%s', 'ALLOW', %d);" % (role, api, sortOrder))
sortOrder += 1
print("Static role permissions from commands.properties have been migrated into the db")


def enableDynamicApiChecker(conn):
runSql(conn, "UPDATE `cloud`.`configuration` SET value='true' where name='dynamic.apichecker.enabled'")
conn.commit()
conn.close()
print("Dynamic role based API checker has been enabled!")


def main():
Expand All @@ -71,6 +79,8 @@ def main():
help="Host or IP of the MySQL server")
parser.add_option("-f", "--properties-file", action="store", type="string", dest="commandsfile", default="/etc/cloudstack/management/commands.properties",
help="The commands.properties file")
parser.add_option("-D", "--default", action="store_true", dest="defaultRules", default=False,
help="")
parser.add_option("-d", "--dryrun", action="store_true", dest="dryrun", default=False,
help="Dry run and debug operations this tool will perform")
(options, args) = parser.parse_args()
Expand All @@ -89,8 +99,14 @@ def main():
port=int(options.port),
db=options.db)

if options.defaultRules:
print("Applying the default role permissions, ignoring any provided properties files(s).")
enableDynamicApiChecker(conn)
sys.exit(0)

if not os.path.isfile(options.commandsfile):
print("Provided commands.properties cannot be accessed or does not exist, please check check permissions")
print("Provided commands.properties cannot be accessed or does not exist.")
print("Please check passed options, or run only with --default option to use the default role permissions.")
sys.exit(1)

while True:
Expand Down Expand Up @@ -122,15 +138,8 @@ def main():

# Migrate rules from commands.properties to cloud.role_permissions
migrateApiRolePermissions(apiMap, conn)
print("Static role permissions from commands.properties have been migrated into the db")

# Enable dynamic role based API checker
runSql(conn, "UPDATE `cloud`.`configuration` SET value='true' where name='dynamic.apichecker.enabled'")
conn.commit()
conn.close()

print("Dynamic role based API checker has been enabled!")

enableDynamicApiChecker(conn)

if __name__ == '__main__':
main()