[
https://issues.apache.org/jira/browse/CLOUDSTACK-8562?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15254236#comment-15254236
]
ASF GitHub Bot commented on CLOUDSTACK-8562:
--------------------------------------------
Github user bhaisaab commented on a diff in the pull request:
https://github.com/apache/cloudstack/pull/1489#discussion_r60771928
--- Diff: scripts/util/migrate-dynamicroles.py ---
@@ -0,0 +1,134 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import os
+import sys
+import uuid
+
+from contextlib import closing
+from optparse import OptionParser
+
+try:
+ import MySQLdb
+except ImportError:
+ print("MySQLdb cannot be imported, please install python-mysqldb(apt)
or mysql-python(yum)")
+ sys.exit(1)
+
+dryrun = False
+
+
+def runSql(conn, query):
+ if dryrun:
+ print("Running SQL query: " + query)
+ return
+ with closing(conn.cursor()) as cursor:
+ cursor.execute(query)
+
+
+def migrateApiRolePermissions(apis, conn):
+ # All allow for root admin role Admin(id:1)
+ runSql(conn, "INSERT INTO `cloud`.`role_permissions` (`uuid`,
`role_id`, `rule`, `permission`) values (UUID(), 1, '*', 'Allow');")
+ # Migrate rules based on commands.properties rule for
ResourceAdmin(id:2), DomainAdmin(id:3), User(id:4)
+ octetKey = {2:2, 3:4, 4:8}
+ for role in [2, 3, 4]:
+ for api in sorted(apis.keys()):
+ # Ignore auth commands
+ if api in ['login', 'logout', 'samlSso', 'samlSlo',
'listIdps', 'listAndSwitchSamlAccount', 'getSPMetadata']:
+ continue
+ if (octetKey[role] & int(apis[api])) > 0:
+ runSql(conn, "INSERT INTO `cloud`.`role_permissions`
(`uuid`, `role_id`, `rule`, `permission`) values (UUID(), %d, '%s', 'Allow');"
% (role, api))
+
+
+def main():
+ parser = OptionParser()
+ parser.add_option("-b", "--db", action="store", type="string",
dest="db", default="cloud",
+ help="The name of the database, default: cloud")
+ parser.add_option("-u", "--user", action="store", type="string",
dest="user", default="cloud",
+ help="User name a MySQL user with privileges on
cloud database")
+ parser.add_option("-p", "--password", action="store", type="string",
dest="password", default="cloud",
+ help="Password of a MySQL user with privileges on
cloud database")
+ parser.add_option("-H", "--host", action="store", type="string",
dest="host", default="127.0.0.1",
+ help="Host or IP of the MySQL server")
+ parser.add_option("-P", "--port", action="store", type="int",
dest="port", default=3306,
+ 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", "--dryrun", action="store_true",
dest="dryrun", default=False,
+ help="Dry run and debug operations this tool will
perform")
+ (options, args) = parser.parse_args()
+
+ print("Apache CloudStack Role Permission Migration Tool")
+ print("(c) Apache CloudStack Authors and the ASF, under the Apache
License, Version 2.0\n")
+
+ global dryrun
+ if options.dryrun:
+ dryrun = True
+
+ conn = MySQLdb.connect(
+ host=options.host,
+ user=options.user,
+ passwd=options.password,
+ port=int(options.port),
+ db=options.db)
+
+ if not os.path.isfile(options.commandsfile):
+ print("Provided commands.properties cannot be accessed or does not
exist, please check check permissions")
+ sys.exit(1)
+
+ while True:
+ choice = raw_input("Running this migration tool will remove any " +
+ "default-role rules in cloud.role_permissions.
" +
+ "Do you want to continue? [y/N]").lower()
+ if choice == 'y':
+ break
+ else:
+ print("Aborting!")
+ sys.exit(1)
+
+ # Generate API to permission octet map
+ apiMap = {}
+ with open(options.commandsfile) as f:
+ for line in f.readlines():
+ if not line or line == '' or line == '\n' or
line.startswith('#'):
+ continue
+ name, value = line.split('=')
+ apiMap[name.strip()] = value.strip()
+
+ # Rename and deprecate old commands.properties file
+ if not dryrun:
+ os.rename(options.commandsfile, options.commandsfile +
'.deprecated')
+ print("The commands.properties file has been deprecated and moved at:
" + options.commandsfile + '.deprecated')
+
+ # Truncate any rules in cloud.role_permissions table
+ runSql(conn, "DELETE FROM `cloud`.`role_permissions` WHERE `role_id`
in (1,2,3,4);")
+
+ # 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()
--- End diff --
The commit() occurs at the very end, in case of an exception they will be
printed on stdout/stderr and script will exit, if I could add a try/except but
that will do the same. The way script performs migration, changes are
idempotent wrt a provided commands.properties file.
> User Definable Roles
> --------------------
>
> Key: CLOUDSTACK-8562
> URL: https://issues.apache.org/jira/browse/CLOUDSTACK-8562
> Project: CloudStack
> Issue Type: New Feature
> Security Level: Public(Anyone can view this level - this is the
> default.)
> Components: Management Server
> Reporter: Paul Angus
> Assignee: Rohit Yadav
>
> Static command.properties moved to database and made user definable
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)