diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java index 53c2340665f..20294d16518 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java @@ -31,6 +31,7 @@ import org.apache.commons.codec.binary.Base64; 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 { @@ -65,10 +66,27 @@ public class Upgrade41000to41100 implements DbUpgrade { @Override public void performDataMigration(Connection conn) { + checkAndEnableDynamicRoles(conn); validateUserDataInBase64(conn); updateSystemVmTemplates(conn); } + private void checkAndEnableDynamicRoles(final Connection conn) { + final Map 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()) { diff --git a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java index fc78268fc62..f3dc3a3b8d7 100644 --- a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java +++ b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java @@ -39,6 +39,7 @@ import com.cloud.utils.component.PluggableService; // 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); diff --git a/scripts/util/migrate-dynamicroles.py b/scripts/util/migrate-dynamicroles.py index cbb83f91783..35dfe662513 100755 --- a/scripts/util/migrate-dynamicroles.py +++ b/scripts/util/migrate-dynamicroles.py @@ -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(): @@ -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() @@ -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: @@ -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()