Skip to content
This repository was archived by the owner on Dec 3, 2024. It is now read-only.

Commit 453a2a9

Browse files
committed
Fixes #31: Minor discrepencies between MySQL and MariaDB
Putting the onus on the user to generate right combination of ClearText and changes/setting AuthPlugin. Also, stop reflecting back GRANT USAGE entry from SHOW GRANTS. Unclear if hashed password returned by MariaDB in this case is concerning or not, but no value in it. Password was always being monitored and updated in the database. Removed TODO.
1 parent 77b5d83 commit 453a2a9

File tree

3 files changed

+32
-36
lines changed

3 files changed

+32
-36
lines changed

api/v1alpha1/databaseuser_types.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ type Identification struct {
5252
// +kubebuilder:validation:Optional
5353
AuthPlugin string `json:"authPlugin"`
5454
// Relates to auth_string, See: MySQL CREATE USER
55-
// TODO: We should watch this object, if it changes we can flush through a new password/token.
5655
// +kubebuilder:validation:Optional
5756
// +nullable
5857
AuthString *SecretKeySource `json:"authString,omitEmpty"`
@@ -129,7 +128,7 @@ func init() {
129128

130129
func (r *DatabaseUser) PermissionListEqual() bool {
131130
// Always has GRANT USAGE as the first one. Only when we have something more complicated than
132-
if len(r.Status.Grants)-1 != len(r.Spec.DatabaseList) {
131+
if len(r.Status.Grants) != len(r.Spec.DatabaseList) {
133132
return false
134133
}
135134
return reflect.DeepEqual(r.Spec.DatabaseList, r.Status.DatabaseList)

config/crd/bases/mysql.apps.cuppett.dev_databaseusers.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ spec:
6969
description: 'Relates to auth_plugin, See: MySQL CREATE USER'
7070
type: string
7171
authString:
72-
description: 'Relates to auth_string, See: MySQL CREATE USER TODO:
73-
We should watch this object, if it changes we can flush through
74-
a new password/token.'
72+
description: 'Relates to auth_string, See: MySQL CREATE USER'
7573
nullable: true
7674
properties:
7775
secretKeyRef:
@@ -158,9 +156,7 @@ spec:
158156
description: 'Relates to auth_plugin, See: MySQL CREATE USER'
159157
type: string
160158
authString:
161-
description: 'Relates to auth_string, See: MySQL CREATE USER TODO:
162-
We should watch this object, if it changes we can flush through
163-
a new password/token.'
159+
description: 'Relates to auth_string, See: MySQL CREATE USER'
164160
nullable: true
165161
properties:
166162
secretKeyRef:

controllers/databaseuser_controller.go

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -183,20 +183,20 @@ func (r *DatabaseUserReconciler) Reconcile(ctx context.Context, req ctrl.Request
183183

184184
if !exists {
185185
err = r.userCreate(ctx, &loop)
186-
if err == nil {
187-
loop.instance.Status.CreationTime = metav1.NewTime(time.Now())
188-
loop.instance.Status.Message = "Created user"
189-
}
186+
loop.instance.Status.CreationTime = metav1.NewTime(time.Now())
187+
loop.instance.Status.Message = "Created user"
190188
} else if loop.adminConnection.UserMine(loop.db, loop.instance) {
191-
updated, err := r.userUpdate(ctx, &loop)
192-
if err == nil && updated {
189+
var updated bool
190+
updated, err = r.userUpdate(ctx, &loop)
191+
if updated {
193192
loop.instance.Status.SyncTime = metav1.NewTime(time.Now())
194193
}
195194
}
196195

197-
err = r.Status().Update(ctx, loop.instance)
198196
if err != nil {
199197
r.Log.Error(err, "Failure to reconcile user.")
198+
} else {
199+
err = r.Status().Update(ctx, loop.instance)
200200
}
201201
}
202202
return ctrl.Result{}, err
@@ -335,9 +335,7 @@ func (r *DatabaseUserReconciler) userUpdate(ctx context.Context, loop *UserLoopC
335335
permsDiff = true
336336
r.Log.Info("Permissions difference.", "Host", loop.adminConnection.Spec.Host,
337337
"Name", loop.instance.Status.Username)
338-
// Always has GRANT USAGE as the first one. Only when we have something more complicated than
339-
// that do we need to revoke it.
340-
if len(loop.instance.Status.Grants) > 1 {
338+
if len(loop.instance.Status.Grants) > 0 {
341339
_, err = r.revoke(loop)
342340
}
343341
if err == nil {
@@ -373,31 +371,30 @@ func (r *DatabaseUserReconciler) userDetailString(ctx context.Context, loop *Use
373371
}
374372
authString = mysqlv1alpha1.Escape(authString)
375373

376-
// Looking for currently known auth_plugin in both places. Where Status has it, grab to hang onto it.
377374
authPlugin = loop.instance.Spec.Identification.AuthPlugin
378-
if authPlugin == "" && loop.instance.Status.Identification != nil {
379-
authPlugin = loop.instance.Status.Identification.AuthPlugin
380-
} else if loop.instance.Status.Identification != nil &&
381-
loop.instance.Spec.Identification.AuthPlugin != loop.instance.Status.Identification.AuthPlugin {
375+
if loop.instance.Status.Identification != nil &&
376+
loop.instance.Spec.Identification.AuthPlugin != loop.instance.Status.Identification.AuthPlugin &&
377+
loop.instance.Spec.Identification.AuthPlugin != "" {
382378
pluginsDiff = true
383379
}
384-
if authPlugin != "" {
385-
authPlugin = mysqlv1alpha1.Escape(authPlugin)
386-
}
380+
authPlugin = mysqlv1alpha1.Escape(authPlugin)
387381

388382
if passwordUpdated || pluginsDiff {
389383
if authPlugin != "" {
390384
queryFragment += " IDENTIFIED WITH '" + authPlugin + "'"
391385
if authString != "" {
386+
// MySQL can do both here
387+
// MariaDB can only do AS (otherwise requires deprecated 5.7 PASSWORD() function to use BY
392388
if loop.instance.Spec.Identification.ClearText {
393389
queryFragment += " BY '" + authString + "'"
394390
} else {
395391
queryFragment += " AS '" + authString + "'"
396392
}
397393
}
398394
} else {
399-
if authString != "" && !update {
395+
if authString != "" {
400396
queryFragment += " IDENTIFIED BY"
397+
// Unique to MARIADB (and maybe MySQL databases <= 5.7?)
401398
if !loop.instance.Spec.Identification.ClearText {
402399
queryFragment += " PASSWORD"
403400
}
@@ -417,7 +414,6 @@ func (r *DatabaseUserReconciler) userDetailString(ctx context.Context, loop *Use
417414
// If this update pass is successful, our identification details will match.
418415
loop.instance.Status.IdentificationResourceVersion = loop.secret.ResourceVersion
419416
loop.instance.Status.Identification = loop.instance.Spec.Identification
420-
loop.instance.Status.Identification.AuthPlugin = authPlugin // For the case where Spec=""
421417
loop.instance.Status.TlsOptions = loop.instance.Spec.TlsOptions
422418
}
423419

@@ -513,14 +509,19 @@ func (r *DatabaseUserReconciler) grantStatusUpdate(loop *UserLoopContext, empty
513509
return false, tx.Error
514510
}
515511

516-
for _, row := range results {
517-
for key := range row {
518-
grant = fmt.Sprintf("%v", row[key])
519-
if !contains(loop.instance.Status.Grants, grant) {
520-
r.Log.Info("Existing grants do not contain this one.", "Grant", grant, "Host",
521-
loop.adminConnection.Spec.Host, "Name", loop.instance.Status.Username)
522-
update = true
523-
loop.instance.Status.Grants = append(loop.instance.Status.Grants, grant)
512+
for i, row := range results {
513+
// Drop the first one in the results.
514+
// It's a useless GRANT USAGE statement.
515+
// On MariaDB it includes the user's password hash.
516+
if i > 0 {
517+
for key := range row {
518+
grant = fmt.Sprintf("%v", row[key])
519+
if !contains(loop.instance.Status.Grants, grant) {
520+
r.Log.Info("Existing grants do not contain this one.", "Grant", grant, "Host",
521+
loop.adminConnection.Spec.Host, "Name", loop.instance.Status.Username)
522+
update = true
523+
loop.instance.Status.Grants = append(loop.instance.Status.Grants, grant)
524+
}
524525
}
525526
}
526527
}

0 commit comments

Comments
 (0)