@@ -62,68 +62,21 @@ public File[] getPrepareScripts() {
6262
6363 @ Override
6464 public void performDataMigration (Connection conn ) {
65- setupRolesAndPermissionsForDynamicRBAC (conn );
65+ setupRolesAndPermissionsForDynamicChecker (conn );
6666 }
6767
68- private void createDefaultRole (final Connection conn , final Long id , final String name , final RoleType roleType ) {
69- final String insertSql = String .format ("INSERT INTO `cloud`.`roles` (`id`, `uuid`, `name`, `role_type`, `description`) values (%d, UUID(), '%s', '%s', 'Default %s role');" ,
70- id , name , roleType .name (), roleType .name ().toLowerCase ());
71- try ( PreparedStatement updatePstmt = conn .prepareStatement (insertSql ) ) {
72- updatePstmt .executeUpdate ();
73- } catch (SQLException e ) {
74- throw new CloudRuntimeException ("Unable to create default role with id: " + id + " name: " + name , e );
75- }
76- }
77-
78- private void createRoleMapping (final Connection conn , final Long roleId , final String apiName ) {
79- final String insertSql = String .format ("INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`) values (UUID(), %d, '%s', 'ALLOW') ON DUPLICATE KEY UPDATE rule=rule;" ,
80- roleId , apiName );
81- try ( PreparedStatement updatePstmt = conn .prepareStatement (insertSql )) {
82- updatePstmt .executeUpdate ();
83- } catch (SQLException ignored ) {
84- s_logger .debug ("Unable to insert mapping for role id:" + roleId + " apiName: " + apiName );
85- }
86- }
87-
88- private void addRoleColumnAndMigrateAccountTable (final Connection conn , final RoleType [] roleTypes ) {
89- // Add role_id column to account table
90- final String alterTableSql = "ALTER TABLE `cloud`.`account` ADD COLUMN `role_id` bigint(20) unsigned COMMENT 'role id for this account' AFTER `type`, " +
91- "ADD KEY `fk_account__role_id` (`role_id`), " +
92- "ADD CONSTRAINT `fk_account__role_id` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`);" ;
93- try (PreparedStatement pstmt = conn .prepareStatement (alterTableSql )) {
94- pstmt .executeUpdate ();
95- s_logger .info ("Altered cloud.account table and added column role_id" );
96- } catch (SQLException e ) {
97- if (e .getMessage ().contains ("role_id" )) {
98- s_logger .warn ("cloud.account table already has the role_id column, skipping altering table and migration of accounts" );
99- return ;
100- } else {
101- throw new CloudRuntimeException ("Unable to create column quota_calculated in table cloud_usage.cloud_usage" , e );
102- }
103- }
104- // Migrate existing account to one of default roles based on account type
105- migrateAccountsToDefaultRoles (conn , roleTypes );
106- }
107-
108- private void migrateAccountsToDefaultRoles (final Connection conn , final RoleType [] roleTypes ) {
109- // Migrate existing accounts to default roles based on account type
110- try (PreparedStatement selectStatement = conn .prepareStatement ("SELECT `id`, `type` FROM `cloud`.`account`;" );
111- ResultSet selectResultSet = selectStatement .executeQuery ()) {
68+ private void migrateAccountsToDefaultRoles (final Connection conn ) {
69+ try (final PreparedStatement selectStatement = conn .prepareStatement ("SELECT `id`, `type` FROM `cloud`.`account`;" );
70+ final ResultSet selectResultSet = selectStatement .executeQuery ()) {
11271 while (selectResultSet .next ()) {
113- Long accountId = selectResultSet .getLong (1 );
114- Short accountType = selectResultSet .getShort (2 );
115- Long roleId = null ;
116- for (RoleType roleType : roleTypes ) {
117- if (roleType .getAccountType () == accountType ) {
118- roleId = roleType .getId ();
119- break ;
120- }
121- }
122- // Skip is account type does not match any of the default roles
123- if (roleId == null ) {
72+ final Long accountId = selectResultSet .getLong (1 );
73+ final Short accountType = selectResultSet .getShort (2 );
74+ final Long roleId = RoleType .getByAccountType (accountType ).getId ();
75+ if (roleId < 1L || roleId > 4L ) {
76+ s_logger .warn ("Skipping role ID migration due to invalid role_id resolved for account id=" + accountId );
12477 continue ;
12578 }
126- try (PreparedStatement updateStatement = conn .prepareStatement ("UPDATE `cloud`.`account` SET role_id = ? WHERE id = ?;" )) {
79+ try (final PreparedStatement updateStatement = conn .prepareStatement ("UPDATE `cloud`.`account` SET account. role_id = ? WHERE account. id = ? ;" )) {
12780 updateStatement .setLong (1 , roleId );
12881 updateStatement .setLong (2 , accountId );
12982 updateStatement .executeUpdate ();
@@ -138,33 +91,25 @@ private void migrateAccountsToDefaultRoles(final Connection conn, final RoleType
13891 s_logger .debug ("Done migrating existing accounts to use one of default roles based on account type" );
13992 }
14093
141- private void setupRolesAndPermissionsForDynamicRBAC (final Connection conn ) {
142- // If there are existing roles, avoid resetting data
143- try (PreparedStatement selectStatement = conn .prepareStatement ("SELECT * FROM `cloud`.`roles`" )) {
144- ResultSet resultSet = selectStatement .executeQuery ();
145- if (resultSet != null && resultSet .next ()) {
146- resultSet .close ();
147- if (s_logger .isDebugEnabled ()) {
148- s_logger .debug ("Found existing roles. Skipping migration of commands.properties to dynamic roles table." );
149- }
94+ private void setupRolesAndPermissionsForDynamicChecker (final Connection conn ) {
95+ final String alterTableSql = "ALTER TABLE `cloud`.`account` " +
96+ "ADD COLUMN `role_id` bigint(20) unsigned COMMENT 'role id for this account' AFTER `type`, " +
97+ "ADD KEY `fk_account__role_id` (`role_id`), " +
98+ "ADD CONSTRAINT `fk_account__role_id` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`);" ;
99+ try (final PreparedStatement pstmt = conn .prepareStatement (alterTableSql )) {
100+ pstmt .executeUpdate ();
101+ } catch (SQLException e ) {
102+ if (e .getMessage ().contains ("role_id" )) {
103+ s_logger .warn ("cloud.account table already has the role_id column, skipping altering table and migration of accounts" );
150104 return ;
105+ } else {
106+ throw new CloudRuntimeException ("Unable to create column quota_calculated in table cloud_usage.cloud_usage" , e );
151107 }
152- } catch (SQLException e ) {
153- s_logger .error ("Unable to find existing roles, if you need to add default roles please add them manually. Giving up!" );
154- return ;
155- }
156-
157- // Add default roles
158- RoleType [] roleTypes = new RoleType [] {RoleType .Admin , RoleType .ResourceAdmin , RoleType .DomainAdmin , RoleType .User };
159- for (RoleType roleType : roleTypes ) {
160- createDefaultRole (conn , roleType .getId (), roleType .name (), roleType );
161108 }
162109
163- // Add role_id column to account and map existing accounts to default roles
164- addRoleColumnAndMigrateAccountTable (conn , roleTypes );
110+ migrateAccountsToDefaultRoles (conn );
165111
166- // Add default set of role-api mapping when commands.properties file is not found
167- Map <String , String > apiMap = PropertiesUtil .processConfigFile (new String [] { PropertiesUtil .getDefaultApiCommandsFileName () });
112+ final Map <String , String > apiMap = PropertiesUtil .processConfigFile (new String [] { PropertiesUtil .getDefaultApiCommandsFileName () });
168113 if (apiMap == null || apiMap .isEmpty ()) {
169114 if (s_logger .isDebugEnabled ()) {
170115 s_logger .debug ("The commands.properties file and default role permissions were not found. " +
@@ -175,33 +120,12 @@ private void setupRolesAndPermissionsForDynamicRBAC(final Connection conn) {
175120 s_logger .error ("Unable to find default role-api mapping sql file, please configure api per role manually" );
176121 return ;
177122 }
178- try (FileReader reader = new FileReader (new File (script )); ) {
123+ try (final FileReader reader = new FileReader (new File (script ))) {
179124 ScriptRunner runner = new ScriptRunner (conn , false , true );
180125 runner .runScript (reader );
181126 } catch (SQLException | IOException e ) {
182127 s_logger .error ("Unable to insert default api-role mappings from file: " + script + ". Please configure api per role manually, giving up!" , e );
183128 }
184- } else {
185- // If commands.properties file exists, use it to create the mappings
186- for (RoleType roleType : roleTypes ) {
187- // Allow all for root admin
188- if (roleType == RoleType .Admin ) {
189- createRoleMapping (conn , roleType .getId (), "*" );
190- continue ;
191- }
192- for (Map .Entry <String , String > entry : apiMap .entrySet ()) {
193- String apiName = entry .getKey ();
194- String roleMask = entry .getValue ();
195- try {
196- short cmdPermissions = Short .parseShort (roleMask );
197- if ((cmdPermissions & roleType .getMask ()) != 0 ) {
198- createRoleMapping (conn , roleType .getId (), apiName );
199- }
200- } catch (NumberFormatException nfe ) {
201- s_logger .info ("Malformed key=value pair for entry: " + entry .toString ());
202- }
203- }
204- }
205129 }
206130 }
207131
0 commit comments