-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add MySQLUser and MySQLAADUser v1alpha2 #1357
Conversation
f26d51e
to
6339871
Compare
Looks like CI failed - could be related to your changes as the tests that failed were some of the negative test cases in MySQLUser? |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
8c68932
to
c35d61f
Compare
It turns out that envtest doesn't yet support conversion webhooks. That means the tests for this PR wouldn't pass without the reconciliation and tests being updated to use the v1alpha2 versions of MySQLUser and MySQLAADUser, so I've included those in this PR (the last two commits). |
This removes DbName from MySQLUser and adds DatabaseRoles to store per-database permissions. Roles will now only store server-wide permissions. Add conversions between v1alpha1 and v1alpha2 versions.
This removes DBName from MySQLAADUser and adds DatabaseRoles to store per-database permissions. Roles will now only store server-wide permissions. Add conversions between v1alpha1 and v1alpha2 versions.
These were set for all types with version conversions but not the others (which aren't in use since they are still commented out in kustomization.yaml). Turning them on in the rest to remove one step in the process of adding conversion webhooks to types in the future. This setting is required for conversion to work - it seems like the only reason it's not set in the patches is that they were generated by kubebuilder before the setting was mandatory.
They now check server-level (in USER_PRIVILEGES) and database-level (SCHEMA_PRIVILEGES) permissions.
c35d61f
to
737c295
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments asking for improved comments in a few places, and then one sorta big comment about the behavior when there are failures reconciling DB permissions.
@@ -168,7 +213,53 @@ func GrantUserRoles(ctx context.Context, user string, database string, roles []s | |||
return nil | |||
} | |||
|
|||
func addRoles(ctx context.Context, db *sql.DB, database string, user string, roles map[string]struct{}) error { | |||
// EnsureUserDatabaseRoles revokes and grants database roles as needed | |||
// so they match the ones passed in. It returns warning messages if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not totally clear how the comment:
It returns warning messages if some databases don't exist
is correct?
- Is
ExtractUserDatabaseRoles
succeeding (but with 0 roles) if the DB doesn't exist? It's not clear to me if that's an error case or an "empty return" case. - Other errors when adding/removing roles will also just get reported as warnings right? As a matter of fact based on my read of this function and its caller it seems like even if we cannot assign some roles to some DBs we will still say
Provisioned = true
andState = "Succeeded"
- that seems probably not correct?
I can sorta see the reasoning around bypassing DB not exists (as maybe next reconcile loop it will), but wonder if we need to be more explicit about checking for errors that aren't that one. Even for that error it might make sense to leave this resource in a "provisioned=false" state as it's not done with all that was asked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes a lot of sense - after our discussion I'll accumulate the errors for different databases into one error from the Ensure function (even though we still apply the roles for the later databases on an error) and have the user still be provisioned=false in the reconciler.
mysql.MySQLServerPort, | ||
adminUser, | ||
adminPassword) | ||
assert.NoError(err) | ||
|
||
expectedRoles := mysql.SliceToSet(updatedRoles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be lacking some tests around the the "DBName doesn't exist" case - it was explicitly mentioned in one of the comments but not sure that this test covers it?
} | ||
|
||
err = mysql.GrantUserRoles(ctx, user, instance.Spec.DbName, instance.Spec.Roles, db) | ||
warnings, err := mysql.EnsureUserDatabaseRoles(ctx, db, user, instance.Spec.DatabaseRoles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here about if we really know that what is ending up in warnings here is something we're ok classifying as a warning.
Also rename the ServerPort and DriverName constants so they don't repeat the name of the package.
And change the reconciliation code for user and aad user to just treat that as a provisioning failure, rather than saying that it had succeeded but there were some errors which is just confusing. We still try to apply changes to all databases even if there is an error for one of them. Also other review changes, thanks @matthchr!
9e3b57e
to
d784570
Compare
The new versions of MySQLUser and MySQLAADUser have roles per-database and server-level roles rather than a user being specific to one database. This adds conversions from v1alpha1 -> v1alpha2 (these are always possible), and supports conversion back to v1alpha1 as long as the user doesn't have any server-level roles and has roles in exactly one database. It also includes the yaml situps to connect the conversion webhooks.
This implements #1346 for MySQL. The initial plan had been to split this change into two PRs with the reconciliation changes in a follow-up, but because envtest doesn't support conversion webhooks the CI tests would have prevented this, so reconciliation and controller tests are included as the last two commits.
How does this PR make you feel:
If applicable: