fix: support multiple MySQL user hosts#13342
Conversation
9f4a39e to
855aa71
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds support for specifying multiple MySQL user hosts (comma-separated) across the MySQL database/user/grant flows, with corresponding backend parsing/normalization and UI updates.
Changes:
- Backend: parse/dedupe comma-separated host lists, apply multi-host creation/grant logic, and add tests for host parsing.
- Frontend: allow entering multiple hosts in MySQL create/user/grant dialogs and adjust user identity display/confirmation.
- Cleanup: remove obsolete i18n strings and ensure DB-scoped user/grant records are deleted when uninstalling MySQL/MariaDB apps.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/views/database/mysql/user/index.vue | Updates MySQL user list/UI to better support host lists and adjusts delete confirmation identity. |
| frontend/src/views/database/mysql/index.vue | Tightens guard condition before opening authorization management. |
| frontend/src/views/database/mysql/create/index.vue | Allows comma-separated permission IPs and avoids loading users/grants when no database is selected. |
| frontend/src/views/database/mysql/bind/index.vue | Enlarges dialog, adds password display/copy UI, and allows comma-separated hosts in grant creation. |
| frontend/src/lang/modules/zh.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/zh-Hant.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/tr.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/ru.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/pt-br.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/ms.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/lo.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/ko.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/ja.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/fa.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/es-es.ts | Removes unused MySQL user-related i18n keys. |
| frontend/src/lang/modules/en.ts | Removes unused MySQL user-related i18n keys. |
| agent/app/service/database_mysql.go | Implements host parsing/deduplication and applies multi-host behavior to create/grant paths. |
| agent/app/service/database_mysql_test.go | Adds unit tests for host splitting/parsing logic. |
| agent/app/service/app_utils.go | Ensures MySQL/MariaDB uninstall deletes related user/grant records in the same transaction context. |
| agent/app/repo/database_user.go | Adds transaction-aware DeleteBy(ctx, ...) API for database user records. |
| agent/app/repo/database_user_grant.go | Adds transaction-aware DeleteBy(ctx, ...) API for database user grant records. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| username: [Rules.requiredInput, Rules.name], | ||
| permission: [Rules.requiredSelect], | ||
| host: [Rules.requiredInput, Rules.noSpace, Rules.illegal], | ||
| host: [Rules.requiredInput, Rules.noSpace, Rules.illegal, { validator: checkUserHosts, trigger: 'blur' }], |
| username: [Rules.requiredInput, Rules.name], | ||
| permission: [Rules.requiredSelect], | ||
| host: [Rules.requiredInput, Rules.noSpace, Rules.illegal], | ||
| host: [Rules.requiredInput, Rules.noSpace, Rules.illegal, { validator: checkMysqlHosts, trigger: 'blur' }], |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (4)
frontend/src/views/database/mysql/user/index.vue:284
- The host field now supports comma-separated hosts (and the UI helper shows comma-separated examples), but keeping Rules.noSpace will reject common inputs like "1.1.1.1, 2.2.2.2" (space after comma). Consider allowing spaces around commas while still rejecting spaces inside each host token.
host: [Rules.requiredInput, Rules.noSpace, Rules.illegal, { validator: checkUserHosts, trigger: 'blur' }],
frontend/src/views/database/mysql/create/index.vue:188
- permissionIPs is intended to accept comma-separated hosts/IPs, but Rules.noSpace will reject inputs with spaces after commas (a common format). Since the validator already trims each token, consider removing Rules.noSpace here and explicitly rejecting spaces inside tokens instead.
permissionIPs: [Rules.requiredInput, Rules.noSpace, Rules.illegal, { validator: checkMysqlHosts, trigger: 'blur' }],
frontend/src/views/database/mysql/bind/index.vue:201
- The host input now supports comma-separated hosts, but Rules.noSpace prevents the common "a, b" format (space after comma). Since the validator trims tokens, consider allowing separator spaces and only rejecting spaces within a token.
host: [Rules.requiredInput, Rules.noSpace, Rules.illegal, { validator: checkMysqlHosts, trigger: 'blur' }],
frontend/src/views/database/mysql/user/index.vue:166
- The delete confirmation helper text is now always the generic "delete this user" message, but deleteUser.isDelete is still tracked. For already-deleted MySQL users (local record only), this text becomes misleading; consider restoring a separate helper message for isDelete=true (and re-adding the related i18n key) so users understand it only removes the 1Panel record.
<span style="font-size: 12px">{{ $t('database.delete') }}</span>
<span style="font-size: 12px; color: red; font-weight: 500">
{{ deleteUserIdentity }}
</span>
<span style="font-size: 12px">{{ $t('database.deleteUserHelper') }}</span>
855aa71 to
c524246
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
agent/app/service/database_mysql.go:901
- Granting privileges to multiple hosts is performed in a loop with early returns on error. If one host grant (or saving the local grant record) fails after earlier hosts succeeded, the method returns an error but leaves a partial set of grants in MySQL and/or partial local records, which can desync 1Panel state from the actual MySQL grants.
for _, host := range hosts {
if err := cli.GrantUser(client.GrantInfo{Database: req.DB, Username: req.Username, Host: host}, 300); err != nil {
return err
}
if err := saveDatabaseUserGrant(dbType, req.Database, req.DB, req.Username, host); err != nil {
return err
}
}
return nil
No description provided.