From ee68d699fa7d60051ee398a08044cb0f7b6ffefb Mon Sep 17 00:00:00 2001 From: tiny-craft <137850705+tiny-craft@users.noreply.github.com> Date: Sun, 8 Oct 2023 01:31:54 +0800 Subject: [PATCH] feat: support sentinel mode #16 #42 --- backend/services/connection_service.go | 15 +++++++ backend/storage/connections.go | 3 ++ backend/types/connection.go | 36 ++++++++++------- .../components/dialogs/ConnectionDialog.vue | 40 +++++++++++++++++-- frontend/src/langs/en.json | 13 +++++- frontend/src/langs/zh-cn.json | 13 +++++- frontend/src/stores/connections.js | 6 +++ 7 files changed, 105 insertions(+), 21 deletions(-) diff --git a/backend/services/connection_service.go b/backend/services/connection_service.go index f780b58..24d0d97 100644 --- a/backend/services/connection_service.go +++ b/backend/services/connection_service.go @@ -127,6 +127,21 @@ func (c *connectionService) createRedisClient(config types.ConnectionConfig) (*r option.ReadTimeout = -2 option.WriteTimeout = -2 } + + if config.Sentinel.Enable { + sentinel := redis.NewSentinelClient(option) + addr, err := sentinel.GetMasterAddrByName(c.ctx, config.Sentinel.Master).Result() + if err != nil { + return nil, err + } + if len(addr) < 2 { + return nil, errors.New("cannot get master address") + } + option.Addr = fmt.Sprintf("%s:%s", addr[0], addr[1]) + option.Username = config.Sentinel.Username + option.Password = config.Sentinel.Password + } + rdb := redis.NewClient(option) return rdb, nil } diff --git a/backend/storage/connections.go b/backend/storage/connections.go index 96b7394..d4ecdb8 100644 --- a/backend/storage/connections.go +++ b/backend/storage/connections.go @@ -37,6 +37,9 @@ func (c *ConnectionsStorage) defaultConnectionItem() types.ConnectionConfig { DBFilterType: "none", DBFilterList: []int{}, MarkColor: "", + Sentinel: types.ConnectionSentinel{ + Master: "mymaster", + }, } } diff --git a/backend/types/connection.go b/backend/types/connection.go index d9b4d75..7c2708f 100644 --- a/backend/types/connection.go +++ b/backend/types/connection.go @@ -3,20 +3,21 @@ package types type ConnectionCategory int type ConnectionConfig struct { - Name string `json:"name" yaml:"name"` - Group string `json:"group,omitempty" yaml:"-"` - Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` - Port int `json:"port,omitempty" yaml:"port,omitempty"` - Username string `json:"username,omitempty" yaml:"username,omitempty"` - Password string `json:"password,omitempty" yaml:"password,omitempty"` - DefaultFilter string `json:"defaultFilter,omitempty" yaml:"default_filter,omitempty"` - KeySeparator string `json:"keySeparator,omitempty" yaml:"key_separator,omitempty"` - ConnTimeout int `json:"connTimeout,omitempty" yaml:"conn_timeout,omitempty"` - ExecTimeout int `json:"execTimeout,omitempty" yaml:"exec_timeout,omitempty"` - DBFilterType string `json:"dbFilterType" yaml:"db_filter_type,omitempty"` - DBFilterList []int `json:"dbFilterList" yaml:"db_filter_list,omitempty"` - MarkColor string `json:"markColor,omitempty" yaml:"mark_color,omitempty"` - SSH ConnectionSSH `json:"ssh,omitempty" yaml:"ssh,omitempty"` + Name string `json:"name" yaml:"name"` + Group string `json:"group,omitempty" yaml:"-"` + Addr string `json:"addr,omitempty" yaml:"addr,omitempty"` + Port int `json:"port,omitempty" yaml:"port,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + DefaultFilter string `json:"defaultFilter,omitempty" yaml:"default_filter,omitempty"` + KeySeparator string `json:"keySeparator,omitempty" yaml:"key_separator,omitempty"` + ConnTimeout int `json:"connTimeout,omitempty" yaml:"conn_timeout,omitempty"` + ExecTimeout int `json:"execTimeout,omitempty" yaml:"exec_timeout,omitempty"` + DBFilterType string `json:"dbFilterType" yaml:"db_filter_type,omitempty"` + DBFilterList []int `json:"dbFilterList" yaml:"db_filter_list,omitempty"` + MarkColor string `json:"markColor,omitempty" yaml:"mark_color,omitempty"` + SSH ConnectionSSH `json:"ssh,omitempty" yaml:"ssh,omitempty"` + Sentinel ConnectionSentinel `json:"sentinel,omitempty" yaml:"sentinel,omitempty"` } type Connection struct { @@ -49,3 +50,10 @@ type ConnectionSSH struct { PKFile string `json:"pkFile,omitempty" yaml:"pk_file,omitempty"` Passphrase string `json:"passphrase,omitempty" yaml:"passphrase,omitempty"` } + +type ConnectionSentinel struct { + Enable bool `json:"enable" yaml:"enable"` + Master string `json:"master" yaml:"master"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` +} diff --git a/frontend/src/components/dialogs/ConnectionDialog.vue b/frontend/src/components/dialogs/ConnectionDialog.vue index c1e86a9..dbc67ba 100644 --- a/frontend/src/components/dialogs/ConnectionDialog.vue +++ b/frontend/src/components/dialogs/ConnectionDialog.vue @@ -198,6 +198,7 @@ const onClose = () => { transform-origin="center"> + { - + + { - + + {{ $t('dialogue.connection.ssh.enable') }} { + + + + + {{ $t('dialogue.connection.sentinel.enable') }} + + + + + + + + + + + + + + + diff --git a/frontend/src/langs/en.json b/frontend/src/langs/en.json index eb9d72d..918eeb7 100644 --- a/frontend/src/langs/en.json +++ b/frontend/src/langs/en.json @@ -114,7 +114,6 @@ "new_title": "New Connection", "edit_title": "Edit Connection", "general": "General", - "advanced": "Advanced", "no_group": "No Group", "group": "Group", "conn_name": "Name", @@ -129,6 +128,7 @@ "test_succ": "Successful connection to redis-server", "test_fail": "Fail Connection", "advn": { + "title": "Advanced", "filter": "Default Key Filter Pattern", "filter_tip": "Pattern which defines loaded keys from redis server", "separator": "Key Separator", @@ -146,8 +146,8 @@ "mark_color": "Mark Color" }, "ssh": { + "title": "SSH Tunnel", "enable": "Enable SSH Tuntel", - "tunnel": "SSH Tunnel", "login_type": "Login Type", "pkfile": "Private Key File", "passphrase": "Passphrase", @@ -157,6 +157,15 @@ "pkfile_tip": "SSH Private Key File Path", "passphrase_tip": "(Optional) Passphrase for Private Key", "pkfile_selection_title": "Please Select Private Key File" + }, + "sentinel": { + "title": "Sentinel", + "enable": "Serve as Sentinel Node", + "master": "Name of Master Node", + "password": "Password for Master Node", + "username": "Username for Master Node", + "pwd_tip": "(Optional) username for master node", + "usr_tip": "(Optional) authentication password for master node (Redis > 6.0)" } }, "group": { diff --git a/frontend/src/langs/zh-cn.json b/frontend/src/langs/zh-cn.json index 776eab7..8368242 100644 --- a/frontend/src/langs/zh-cn.json +++ b/frontend/src/langs/zh-cn.json @@ -114,7 +114,6 @@ "new_title": "新建连接", "edit_title": "编辑连接", "general": "常规配置", - "advanced": "高级配置", "no_group": "无分组", "group": "分组", "conn_name": "连接名", @@ -129,6 +128,7 @@ "test_succ": "成功连接到Redis服务器", "test_fail": "连接失败", "advn": { + "title": "高级配置", "filter": "默认键过滤表达式", "filter_tip": "需要加载的键名表达式", "separator": "键分隔符", @@ -147,7 +147,7 @@ }, "ssh": { "enable": "启用SSH隧道", - "tunnel": "SSH隧道", + "title": "SSH隧道", "login_type": "登录类型", "pkfile": "私钥文件", "passphrase": "私钥密码", @@ -157,6 +157,15 @@ "pkfile_tip": "SSH私钥文件路径", "passphrase_tip": "(可选)SSH私钥密码", "pkfile_selection_title": "请选择私钥文件" + }, + "sentinel": { + "title": "哨兵模式", + "enable": "当前为哨兵节点", + "master": "主实例名", + "password": "主节点密码", + "username": "主节点用户名", + "pwd_tip": "(可选)主节点服务授权用户名", + "usr_tip": "(可选)主节点服务授权密码 (Redis > 6.0)" } }, "group": { diff --git a/frontend/src/stores/connections.js b/frontend/src/stores/connections.js index 8ab10ad..a998366 100644 --- a/frontend/src/stores/connections.js +++ b/frontend/src/stores/connections.js @@ -221,6 +221,12 @@ const useConnectionStore = defineStore('connections', { pkFile: '', passphrase: '', }, + sentinel: { + enable: false, + master: 'mymaster', + username: '', + password: '', + }, } },