Skip to content

Commit e18ff60

Browse files
Prevent upgrade failures if there are existing annotations permissions (apache#5846)
* Do not fail if there are existing role permissions for annotations * Refactor * Improve refactor * Do not update if there are existing role permissions for annotations * Fix exception on upgrade * Remove extra space from suggestion * Apply suggestions from code review Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com>
1 parent f5b0d2f commit e18ff60

3 files changed

Lines changed: 88 additions & 11 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.upgrade;
18+
19+
import org.apache.log4j.Logger;
20+
21+
import java.sql.Connection;
22+
import java.sql.PreparedStatement;
23+
import java.sql.ResultSet;
24+
import java.sql.SQLException;
25+
26+
public class RolePermissionChecker {
27+
28+
final static Logger LOG = Logger.getLogger(RolePermissionChecker.class);
29+
30+
private static final String checkAnnotationRulesPermissionPreparedStatement =
31+
"SELECT permission FROM `cloud`.`role_permissions` WHERE role_id = ? AND rule = ?";
32+
private static final String insertAnnotationRulePermissionPreparedStatement =
33+
"INSERT IGNORE INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), ?, ?, 'ALLOW')";
34+
35+
public RolePermissionChecker() {
36+
}
37+
38+
public boolean existsRolePermissionByRoleIdAndRule(Connection conn, long roleId, String rule) {
39+
try {
40+
PreparedStatement pstmt = conn.prepareStatement(checkAnnotationRulesPermissionPreparedStatement);
41+
pstmt.setLong(1, roleId);
42+
pstmt.setString(2, rule);
43+
ResultSet rs = pstmt.executeQuery();
44+
return rs != null && rs.next();
45+
} catch (SQLException e) {
46+
LOG.error("Error on existsRolePermissionByRoleIdAndRule: " + e.getMessage(), e);
47+
return false;
48+
}
49+
}
50+
51+
public void insertAnnotationRulePermission(Connection conn, long roleId, String rule) {
52+
try {
53+
PreparedStatement pstmt = conn.prepareStatement(insertAnnotationRulePermissionPreparedStatement);
54+
pstmt.setLong(1, roleId);
55+
pstmt.setString(2, rule);
56+
pstmt.executeUpdate();
57+
} catch (SQLException e) {
58+
LOG.error("Error on insertAnnotationRulePermission: " + e.getMessage(), e);
59+
}
60+
}
61+
}

engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41520to41600.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@
2222
import java.sql.PreparedStatement;
2323
import java.sql.ResultSet;
2424
import java.sql.SQLException;
25+
import java.util.Arrays;
26+
import java.util.List;
2527

28+
import com.cloud.upgrade.RolePermissionChecker;
2629
import com.cloud.upgrade.SystemVmTemplateRegistration;
30+
import org.apache.cloudstack.acl.RoleType;
2731
import org.apache.log4j.Logger;
2832

2933
import com.cloud.utils.exception.CloudRuntimeException;
@@ -32,6 +36,7 @@ public class Upgrade41520to41600 implements DbUpgrade, DbUpgradeSystemVmTemplate
3236

3337
final static Logger LOG = Logger.getLogger(Upgrade41520to41600.class);
3438
private SystemVmTemplateRegistration systemVmTemplateRegistration;
39+
private RolePermissionChecker rolePermissionChecker = new RolePermissionChecker();
3540

3641
public Upgrade41520to41600() {
3742
}
@@ -65,6 +70,28 @@ public InputStream[] getPrepareScripts() {
6570
@Override
6671
public void performDataMigration(Connection conn) {
6772
generateUuidForExistingSshKeyPairs(conn);
73+
populateAnnotationPermissions(conn);
74+
}
75+
76+
private void populateAnnotationPermissions(Connection conn) {
77+
List<String> annotationRules = Arrays.asList("listAnnotations", "addAnnotation", "removeAnnotation");
78+
for (RoleType roleType : Arrays.asList(RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User)) {
79+
checkAndPersistAnnotationPermissions(conn, roleType, annotationRules);
80+
}
81+
}
82+
83+
private void checkAndPersistAnnotationPermissions(Connection conn, RoleType roleType, List<String> rules) {
84+
LOG.debug("Checking the annotation permissions for the role: " + roleType.getId());
85+
for (String rule : rules) {
86+
LOG.debug("Checking the annotation permissions for the role: " + roleType.getId() + " and rule: " + rule);
87+
if (!rolePermissionChecker.existsRolePermissionByRoleIdAndRule(conn, roleType.getId(), rule)) {
88+
LOG.debug("Inserting role permission for role: " + roleType.getId() + " and rule: " + rule);
89+
rolePermissionChecker.insertAnnotationRulePermission(conn, roleType.getId(), rule);
90+
} else {
91+
LOG.debug("Found existing role permission for role: " + roleType.getId() + " and rule: " + rule +
92+
", not updating it");
93+
}
94+
}
6895
}
6996

7097
private void generateUuidForExistingSshKeyPairs(Connection conn) {

engine/schema/src/main/resources/META-INF/db/schema-41520to41600.sql

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -727,17 +727,6 @@ CREATE TABLE `cloud`.`resource_icon` (
727727

728728
ALTER TABLE `cloud`.`annotations` ADD COLUMN `admins_only` tinyint(1) unsigned NOT NULL DEFAULT 1;
729729

730-
-- Allow annotations for resource admins, domain admins and users
731-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 2, 'listAnnotations', 'ALLOW');
732-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 2, 'addAnnotation', 'ALLOW');
733-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 2, 'removeAnnotation', 'ALLOW');
734-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 3, 'listAnnotations', 'ALLOW');
735-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 3, 'addAnnotation', 'ALLOW');
736-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 3, 'removeAnnotation', 'ALLOW');
737-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 4, 'listAnnotations', 'ALLOW');
738-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 4, 'addAnnotation', 'ALLOW');
739-
INSERT INTO `cloud`.`role_permissions` (uuid, role_id, rule, permission) VALUES (UUID(), 4, 'removeAnnotation', 'ALLOW');
740-
741730
-- Add uuid for ssh keypairs
742731
ALTER TABLE `cloud`.`ssh_keypairs` ADD COLUMN `uuid` varchar(40) AFTER `id`;
743732

0 commit comments

Comments
 (0)