1
1
from mysqlsh .plugin_manager import plugin , plugin_function
2
2
from mysqlsh_plugins_common import get_major_version
3
+ from mysqlsh_plugins_common import get_distro
3
4
from user import mds
4
5
5
6
import re
6
7
7
8
8
9
def _get_server_info (session ):
9
- return session .run_sql ("""SELECT CONCAT(@@hostname," (",@@version,")")""" ).fetch_one ()[0 ]
10
+ return session .run_sql (
11
+ """SELECT CONCAT(@@hostname," (",@@version,")")"""
12
+ ).fetch_one ()[0 ]
10
13
11
14
12
15
@plugin_function ("user.clone" )
13
- def copy_users_grants (userfrom = None , userto = None , dryrun = False , ocimds = False , force = False , session = None ):
16
+ def copy_users_grants (
17
+ userfrom = None , userto = None , dryrun = False , ocimds = False , force = False , session = None
18
+ ):
14
19
"""
15
20
Clone a user to the same server
16
21
@@ -26,17 +31,22 @@ def copy_users_grants(userfrom=None, userto=None, dryrun=False, ocimds=False, fo
26
31
"""
27
32
# Get hold of the global shell object
28
33
import mysqlsh
34
+
29
35
shell = mysqlsh .globals .shell
30
36
old_format = None
31
37
32
38
if session is None :
33
39
session = shell .get_session ()
34
40
if session is None :
35
- print ("No session specified. Either pass a session object to this "
36
- "function or connect the shell to a database" )
41
+ print (
42
+ "No session specified. Either pass a session object to this "
43
+ "function or connect the shell to a database"
44
+ )
37
45
return
38
46
if not userfrom :
39
- search_string = shell .prompt ("Enter the user to search (you can use wildcards '%', leave blank for all): " )
47
+ search_string = shell .prompt (
48
+ "Enter the user to search (you can use wildcards '%', leave blank for all): "
49
+ )
40
50
if len (search_string .strip ()) > 0 :
41
51
search_string = 'AND user LIKE "{}"' .format (search_string )
42
52
else :
@@ -46,15 +56,21 @@ def copy_users_grants(userfrom=None, userto=None, dryrun=False, ocimds=False, fo
46
56
print ("Info: locked users and users having expired password are not listed." )
47
57
48
58
mysql_version = get_major_version (session )
49
- mysql_major_int = int (mysql_version .split ('.' )[0 ])
59
+ mysql_major_int = int (mysql_version .split ("." )[0 ])
60
+ mysql_distro = get_distro (session )
61
+ if mysql_distro .lower ().startswith ("maria" ):
62
+ print ("-- MariaDB Detected and not supported" )
63
+ return
50
64
if mysql_major_int >= 8 or mysql_version == "5.7" :
51
65
# Get the list of users
52
66
stmt = """SELECT DISTINCT User, Host,
53
67
IF(authentication_string = "","NO", "YES") HAS_PWD
54
68
FROM mysql.user
55
69
WHERE NOT( `account_locked`="Y" AND `password_expired`="Y" AND `authentication_string`="" ) {}
56
70
ORDER BY User, Host;
57
- """ .format (search_string )
71
+ """ .format (
72
+ search_string
73
+ )
58
74
else :
59
75
stmt = """SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
60
76
WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME='user' AND COLUMN_NAME='password';"""
@@ -65,86 +81,115 @@ def copy_users_grants(userfrom=None, userto=None, dryrun=False, ocimds=False, fo
65
81
FROM mysql.user
66
82
WHERE NOT(`password_expired`="Y" AND `authentication_string`="" ) {}
67
83
ORDER BY User, Host;
68
- """ .format (search_string )
84
+ """ .format (
85
+ search_string
86
+ )
69
87
else :
70
88
stmt = """SELECT DISTINCT User, Host,
71
89
IF(authentication_string = "","NO", "YES") HAS_PWD
72
90
FROM mysql.user
73
91
WHERE NOT(`password_expired`="Y" AND `authentication_string`="" ) {}
74
92
ORDER BY User, Host;
75
- """ .format (search_string )
76
- users = session .run_sql (stmt ).fetch_all ()
93
+ """ .format (
94
+ search_string
95
+ )
96
+ users = session .run_sql (stmt ).fetch_all ()
77
97
final_s = ""
78
- if len (users )> 1 :
98
+ if len (users ) > 1 :
79
99
final_s = "s"
80
100
print ("{} user{} found!" .format (len (users ), final_s ))
81
101
for user in users :
82
102
if ocimds and user [2 ] == "NO" :
83
- print ("[`{}`@`{}`] is not compatible with OCI MDS as it has not password, ignoring it..." .format (user [0 ], user [1 ]))
103
+ print (
104
+ "[`{}`@`{}`] is not compatible with OCI MDS as it has not password, ignoring it..." .format (
105
+ user [0 ], user [1 ]
106
+ )
107
+ )
84
108
continue
85
109
if not force :
86
- answer = shell .prompt ("Do you want to clone [`{}`@`{}`] ? (y/N) " .format (user [0 ], user [1 ]), {'defaultValue' : 'n' })
110
+ answer = shell .prompt (
111
+ "Do you want to clone [`{}`@`{}`] ? (y/N) " .format (user [0 ], user [1 ]),
112
+ {"defaultValue" : "n" },
113
+ )
87
114
else :
88
115
answer = "y"
89
- if answer .lower () == 'y' :
116
+ if answer .lower () == "y" :
90
117
if mysql_major_int >= 8 :
91
118
stmt = """SELECT from_user, from_host FROM mysql.role_edges WHERE to_user = ? and to_host = ?"""
92
119
roles = session .run_sql (stmt , [user [0 ], user [1 ]]).fetch_all ()
93
- if len (roles )> 0 :
120
+ if len (roles ) > 0 :
94
121
for role in roles :
95
- stmt = """SHOW GRANTS FOR `{}`@`{}`""" .format (role [0 ], role [1 ])
96
- grants = session .run_sql (stmt ).fetch_all ()
97
- for grant in grants :
98
- if ocimds :
99
- grant_stmt = grant [0 ]
100
- on_stmt = re .sub (r"^.*( ON .*\..* TO .*$)" ,r"\1" , grant_stmt )
101
- grant_stmt_tmp = re .sub ('^GRANT ' ,'' , grant_stmt )
102
- grant_stmt_tmp = re .sub (' ON .*\..* TO .*$' ,'' , grant_stmt_tmp )
103
- tab_grants = grant_stmt_tmp .split (', ' )
104
- tab_list = []
105
- for priv in tab_grants :
106
- for allowed_priv in mds .mds_allowed_privileges :
107
- if allowed_priv == priv :
108
- tab_list .append (allowed_priv )
109
- break
110
- if len (tab_list )> 0 :
111
- grant_stmt = "GRANT " + ', ' .join (tab_list ) + on_stmt
112
- else :
113
- grant_stmt = None
114
-
122
+ stmt = """SHOW GRANTS FOR `{}`@`{}`""" .format (role [0 ], role [1 ])
123
+ grants = session .run_sql (stmt ).fetch_all ()
124
+ for grant in grants :
125
+ if ocimds :
126
+ grant_stmt = grant [0 ]
127
+ on_stmt = re .sub (
128
+ r"^.*( ON .*\..* TO .*$)" , r"\1" , grant_stmt
129
+ )
130
+ grant_stmt_tmp = re .sub ("^GRANT " , "" , grant_stmt )
131
+ grant_stmt_tmp = re .sub (
132
+ " ON .*\..* TO .*$" , "" , grant_stmt_tmp
133
+ )
134
+ tab_grants = grant_stmt_tmp .split (", " )
135
+ tab_list = []
136
+ for priv in tab_grants :
137
+ for allowed_priv in mds .mds_allowed_privileges :
138
+ if allowed_priv == priv :
139
+ tab_list .append (allowed_priv )
140
+ break
141
+ if len (tab_list ) > 0 :
142
+ grant_stmt = (
143
+ "GRANT " + ", " .join (tab_list ) + on_stmt
144
+ )
115
145
else :
116
- grant_stmt = grant [0 ]
117
- if grant_stmt :
118
- grant_stmt = grant_stmt .replace ("TO `{}`@`{}`" .format (user [0 ], user [1 ]), "TO {}" .format (userto ))
119
- if dryrun :
120
- print ("{};" .format (grant_stmt ))
121
- else :
122
- try :
123
- session .run_sql (grant_stmt )
124
- except mysqlsh .DBError as err :
125
- print ("Aborting: {}" .format (err ))
126
- return
146
+ grant_stmt = None
127
147
148
+ else :
149
+ grant_stmt = grant [0 ]
150
+ if grant_stmt :
151
+ grant_stmt = grant_stmt .replace (
152
+ "TO `{}`@`{}`" .format (user [0 ], user [1 ]),
153
+ "TO {}" .format (userto ),
154
+ )
155
+ if dryrun :
156
+ print ("{};" .format (grant_stmt ))
157
+ else :
158
+ try :
159
+ session .run_sql (grant_stmt )
160
+ except mysqlsh .DBError as err :
161
+ print ("Aborting: {}" .format (err ))
162
+ return
128
163
129
164
if mysql_major_int < 8 and mysql_version != "5.7" :
130
- stmt = """SHOW GRANTS FOR `{}`@`{}`""" .format (user [0 ], user [1 ])
131
- create_user = session .run_sql (stmt ).fetch_one ()[0 ] + ";"
132
- create_user = create_user .replace (" TO '{}'@'{}'" .format (user [0 ], user [1 ]),"CREATE USER {}" .format (userto ))
133
- create_user = re .sub (r".*CREATE USER " ,"CREATE USER " , create_user )
165
+ stmt = """SHOW GRANTS FOR `{}`@`{}`""" .format (user [0 ], user [1 ])
166
+ create_user = session .run_sql (stmt ).fetch_one ()[0 ] + ";"
167
+ create_user = create_user .replace (
168
+ " TO '{}'@'{}'" .format (user [0 ], user [1 ]),
169
+ "CREATE USER {}" .format (userto ),
170
+ )
171
+ create_user = re .sub (r".*CREATE USER " , "CREATE USER " , create_user )
134
172
else :
135
- stmt = """SHOW CREATE USER `{}`@`{}`""" .format (user [0 ], user [1 ])
136
- create_user = session .run_sql (stmt ).fetch_one ()[0 ] + ";"
137
- #print("-- DEBUG: {}".format(create_user))
138
- create_user = create_user .replace ("CREATE USER `{}`@`{}`" .format (user [0 ], user [1 ]),"CREATE USER IF NOT EXISTS {}" .format (userto ))
139
- #print("-- DEBUG: {}".format(create_user))
140
- # we need to find the password in binary format
141
- stmt = """SELECT authentication_string, convert(authentication_string using binary) authbin
142
- FROM mysql.user where user='{}' and host='{}'""" .format (user [0 ], user [1 ])
143
- auth_user = session .run_sql (stmt ).fetch_one ()
144
- auth_string = auth_user [0 ]
145
- auth_string_bin = auth_user [1 ]
146
- hex_string = auth_string_bin .hex ()
147
- create_user = re .sub (r" AS '(.*)' " , r" AS 0x{} " .format (hex_string ), create_user )
173
+ stmt = """SHOW CREATE USER `{}`@`{}`""" .format (user [0 ], user [1 ])
174
+ create_user = session .run_sql (stmt ).fetch_one ()[0 ] + ";"
175
+ # print("-- DEBUG: {}".format(create_user))
176
+ create_user = create_user .replace (
177
+ "CREATE USER `{}`@`{}`" .format (user [0 ], user [1 ]),
178
+ "CREATE USER IF NOT EXISTS {}" .format (userto ),
179
+ )
180
+ # print("-- DEBUG: {}".format(create_user))
181
+ # we need to find the password in binary format
182
+ stmt = """SELECT authentication_string, convert(authentication_string using binary) authbin
183
+ FROM mysql.user where user='{}' and host='{}'""" .format (
184
+ user [0 ], user [1 ]
185
+ )
186
+ auth_user = session .run_sql (stmt ).fetch_one ()
187
+ auth_string = auth_user [0 ]
188
+ auth_string_bin = auth_user [1 ]
189
+ hex_string = auth_string_bin .hex ()
190
+ create_user = re .sub (
191
+ r" AS '(.*)' " , r" AS 0x{} " .format (hex_string ), create_user
192
+ )
148
193
if dryrun :
149
194
print ("-- User `{}`@`{}`" .format (user [0 ], user [1 ]))
150
195
print (create_user )
@@ -159,42 +204,48 @@ def copy_users_grants(userfrom=None, userto=None, dryrun=False, ocimds=False, fo
159
204
160
205
stmt = """SHOW GRANTS FOR `{}`@`{}`""" .format (user [0 ], user [1 ])
161
206
grants = session .run_sql (stmt ).fetch_all ()
162
- if not dryrun and len (grants )> 0 :
163
- print ("Copying GRANTS." , end = '' )
207
+ if not dryrun and len (grants ) > 0 :
208
+ print ("Copying GRANTS." , end = "" )
164
209
for grant in grants :
165
210
if "IDENTIFIED BY PASSWORD" in grant [0 ]:
166
- grant_stmt = re .sub (r" IDENTIFIED BY PASSWORD.*$" ,"" , grant [0 ])
211
+ grant_stmt = re .sub (r" IDENTIFIED BY PASSWORD.*$" , "" , grant [0 ])
167
212
else :
168
213
grant_stmt = grant [0 ]
169
214
if ocimds :
170
- on_stmt = re .sub (r"^.*( ON .*\..* TO .*$)" ,r"\1" , grant_stmt )
171
- grant_stmt_tmp = re .sub (' ^GRANT ' , '' , grant_stmt )
172
- grant_stmt_tmp = re .sub (' ON .*\..* TO .*$' , '' , grant_stmt_tmp )
173
- tab_grants = grant_stmt_tmp .split (', ' )
215
+ on_stmt = re .sub (r"^.*( ON .*\..* TO .*$)" , r"\1" , grant_stmt )
216
+ grant_stmt_tmp = re .sub (" ^GRANT " , "" , grant_stmt )
217
+ grant_stmt_tmp = re .sub (" ON .*\..* TO .*$" , "" , grant_stmt_tmp )
218
+ tab_grants = grant_stmt_tmp .split (", " )
174
219
tab_list = []
175
220
for priv in tab_grants :
176
221
for allowed_priv in mds .mds_allowed_privileges :
177
222
if allowed_priv == priv :
178
223
tab_list .append (allowed_priv )
179
224
break
180
- if len (tab_list )> 0 :
181
- grant_stmt = "GRANT " + ', ' .join (tab_list ) + on_stmt
225
+ if len (tab_list ) > 0 :
226
+ grant_stmt = "GRANT " + ", " .join (tab_list ) + on_stmt
182
227
else :
183
- grant_stmt = None
228
+ grant_stmt = None
184
229
if grant_stmt :
185
- grant_stmt = grant_stmt .replace ("TO `{}`@`{}`" .format (user [0 ], user [1 ]), "TO {}" .format (userto ))
186
- grant_stmt = grant_stmt .replace ("TO '{}'@'{}'" .format (user [0 ], user [1 ]), "TO {}" .format (userto ))
230
+ grant_stmt = grant_stmt .replace (
231
+ "TO `{}`@`{}`" .format (user [0 ], user [1 ]), "TO {}" .format (userto )
232
+ )
233
+ grant_stmt = grant_stmt .replace (
234
+ "TO '{}'@'{}'" .format (user [0 ], user [1 ]), "TO {}" .format (userto )
235
+ )
187
236
if dryrun :
188
237
print ("{};" .format (grant_stmt ))
189
238
else :
190
239
try :
191
240
session .run_sql (grant_stmt )
192
- print ("." , end = '' )
241
+ print ("." , end = "" )
193
242
except mysqlsh .DBError as err :
194
243
print ("\n Aborting: {}" .format (err ))
195
- print ("You may need to install mysql-client to save the password." )
244
+ print (
245
+ "You may need to install mysql-client to save the password."
246
+ )
196
247
return
197
- if not dryrun and len (grants )> 0 :
248
+ if not dryrun and len (grants ) > 0 :
198
249
print ("\n User(s) copied successfully!" )
199
250
200
251
return
0 commit comments