1. 概述
在上一篇文章 etcd学习 中我们搭建好了 Etcd 集群,并使用 etcdctl 进行了大部分命令的测试,这篇文章,将使用 golang 来对接 etcd 的这些命令。
这里我们使用的是官方的 golang 客户端 :
go get go.etcd.io/etcd/client/v3
以下是各个模块及命令的使用情况,所有代码托管在 Github :
模块 | 命令 | 说明 | 进度 |
---|---|---|---|
version | version | 查看版本信息 | — |
endpoint | endpoint status | 查看节点状态 | ✅ |
endpoint hashkv | 查看节点历史hash | ✅ | |
endpoint health | 查看节点健康状况 | — | |
member | member list | 获取成员列表 | ✅ |
member add | 添加成员 | ✅ | |
member update | 更新成员 | ✅ | |
member promote | 提升学习者成员为常规成员 | ✅ | |
member remove | 移除成员 | ✅ | |
move-leader | move-leader | 将节点设为leader | ✅ |
auth | auth status | 查看当前鉴权开启状态 | ✅ |
auth disable | 禁用鉴权 | ✅ | |
auth enable | 启用鉴权 | ✅ | |
role | role list | 获取角色列表 | ✅ |
role add | 添加角色 | ✅ | |
role get | 查看角色信息 | ✅ | |
role delete | 删除角色 | ✅ | |
role grant-permission | 角色授权 | ✅ | |
role revoke-permission | 撤销角色授权 | ✅ | |
user | user add | 添加用户 | ✅ |
user list | 用户列表 | ✅ | |
user get | 获取用户信息 | ✅ | |
user delete | 删除用户 | ✅ | |
user passwd | 修改密码 | ✅ | |
user grant-role | 用户绑定角色 | ✅ | |
user revoke-role | 撤销用户角色 | ✅ | |
lease | lease list | 租约列表 | ✅ |
lease grant | 生成租约 | ✅ | |
lease revoke | 撤销租约 | ✅ | |
lease timetolive | 查看租约期限信息 | ✅ | |
lease keep-alive | 保持租约不过期 | ✅ | |
normal | put | 设置kv | ✅ |
get | 查看kv | ✅ | |
del | 删除kv | ✅ | |
watch | 监听key | ✅ | |
txn | txn | 开启事务 | ✅ |
lock | lock | 分布式锁 | ✅ |
snapshot | snapshot save | 保存快照 | ✅ |
snapshot status | 校验快照 | — | |
snapshot restore | 从快照恢复 | — | |
alarm | alarm list | 获取警报列表 | ✅ |
alarm disarm | 解除警报 | ✅ | |
check | check datascale | 检查内存使用情况 | ✅ |
check perf | 查看集群性能 | ✅ | |
other | compaction | 压缩 etcd 中的事件历史 | — |
completion | 生成完成脚本 | — | |
defrag | 对具有给定端点的 etcd 成员的存储进行碎片整理 | — | |
elect | 观察并参与leader选举 | — | |
make-mirror | 在目标 etcd 集群上创建镜像 | — |
2. 使用
代码中 helper.PrintJSON(res)
只是一个简单的封装打印的方法,目的就是将响应结果打印为 json。
package helper
import (
"encoding/json"
"fmt"
)
// PrintJSON 打印Json
func PrintJSON(v interface{}) {
b, _ := json.Marshal(v)
fmt.Printf("%s\n", b)
}
2.1 endpoint
endpoint 封装了 endpoint status 和 endpoint hashkv 两个命令的方法,如下:
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
)
// Status 查看状态
func Status() error {
for _, v := range cli.Endpoints() {
res, err := cli.Status(ctx, v)
if err != nil {
return err
}
helper.PrintJSON(res)
}
return nil
}
// HashKV 查看节点历史hash
func HashKV() error {
for _, v := range cli.Endpoints() {
res, err := cli.HashKV(ctx, v, 0)
if err != nil {
return err
}
helper.PrintJSON(res)
}
return nil
}
2.2 member / move-leader
package base
import "github.com/jormin/etcd-demo/pkg/helper"
// MemberList 节点列表
func MemberList() error {
res, err := cli.MemberList(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// MemberAdd 添加常规节点
func MemberAdd(peerAddrs []string) error {
res, err := cli.MemberAdd(ctx, peerAddrs)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// MemberAddLearner 添加学习者节点
func MemberAddLearner(peerAddrs []string) error {
res, err := cli.MemberAddAsLearner(ctx, peerAddrs)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// MemberUpdate 成员更新
func MemberUpdate(id uint64, peerAddrs []string) error {
res, err := cli.MemberUpdate(ctx, id, peerAddrs)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// MemberPromote 提升学习者节点为常规节点
func MemberPromote(id uint64) error {
res, err := cli.MemberPromote(ctx, id)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// MemberRemove 删除成员
func MemberRemove(id uint64) error {
res, err := cli.MemberRemove(ctx, id)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// MoveLeader 提升为leader
func MoveLeader(id uint64) error {
res, err := cli.MoveLeader(ctx, id)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
2.3 auth
package base
import "github.com/jormin/etcd-demo/pkg/helper"
// AuthStatus 获取鉴权开启状态
func AuthStatus() error {
res, err := cli.AuthStatus(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// AuthDisable 关闭鉴权
func AuthDisable() error {
res, err := cli.AuthDisable(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// AuthEnable 启动鉴权
func AuthEnable() error {
res, err := cli.AuthEnable(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
2.4 role
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
clientv3 "go.etcd.io/etcd/client/v3"
)
// RoleList 获取角色列表
func RoleList() error {
res, err := cli.RoleList(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// RoleAdd 添加角色
func RoleAdd(role string) error {
res, err := cli.RoleAdd(ctx, role)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// RoleGet 获取角色信息
func RoleGet(role string) error {
res, err := cli.RoleGet(ctx, role)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// RoleDelete 删除角色
func RoleDelete(role string) error {
res, err := cli.RoleDelete(ctx, role)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// RoleGrantPermission 赋予角色权限
func RoleGrantPermission(role string, key, rangeEnd string, permType clientv3.PermissionType) error {
res, err := cli.RoleGrantPermission(ctx, role, key, rangeEnd, permType)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// RoleRevokePermission 撤销角色权限
func RoleRevokePermission(role string, key, rangeEnd string) error {
res, err := cli.RoleRevokePermission(ctx, role, key, rangeEnd)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
2.5 user
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
clientv3 "go.etcd.io/etcd/client/v3"
)
// UserList 获取用户列表
func UserList() error {
res, err := cli.UserList(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserAdd 添加用户
func UserAdd(name, password string) error {
res, err := cli.UserAdd(ctx, name, password)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserAddWithOptions 使用选项添加用户
func UserAddWithOptions(name, password string, options *clientv3.UserAddOptions) error {
res, err := cli.UserAddWithOptions(ctx, name, password, options)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserChangePasswd 修改密码
func UserChangePasswd(name, password string) error {
res, err := cli.UserChangePassword(ctx, name, password)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserGet 获取用户信息
func UserGet(name string) error {
res, err := cli.UserGet(ctx, name)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserDelete 删除用户
func UserDelete(name string) error {
res, err := cli.UserDelete(ctx, name)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserGrantRole 赋予用户角色
func UserGrantRole(name, role string) error {
res, err := cli.UserGrantRole(ctx, name, role)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// UserRevokeRole 撤销用户角色
func UserRevokeRole(name, role string) error {
res, err := cli.UserRevokeRole(ctx, name, role)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
2.6 lease
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
clientv3 "go.etcd.io/etcd/client/v3"
)
// LeaseList 获取租约列表
func LeaseList() error {
res, err := cli.Leases(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// LeaseGrant 生成租约
func LeaseGrant(ttl int64) error {
res, err := cli.Grant(ctx, ttl)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// LeaseRevoke 撤销租约
func LeaseRevoke(id int64) error {
res, err := cli.Revoke(ctx, clientv3.LeaseID(id))
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// LeaseTimeToLive 租约信息
func LeaseTimeToLive(id int64, opts ...clientv3.LeaseOption) error {
res, err := cli.TimeToLive(ctx, clientv3.LeaseID(id), opts...)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// LeaseKeepAlive 保持租约不过期
func LeaseKeepAlive(id int64) error {
res, err := cli.KeepAlive(ctx, clientv3.LeaseID(id))
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// LeaseKeepAliveOnce 更新租约一次
func LeaseKeepAliveOnce(id int64) error {
res, err := cli.KeepAliveOnce(ctx, clientv3.LeaseID(id))
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
2.7 normal
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
clientv3 "go.etcd.io/etcd/client/v3"
)
// Put 设置值
func Put(key, val string, opts ...clientv3.OpOption) error {
res, err := cli.Put(ctx, key, val, opts...)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// Get 获取值
func Get(key string, opts ...clientv3.OpOption) error {
res, err := cli.Get(ctx, key, opts...)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// Delete 删除键值对
func Delete(key string, opts ...clientv3.OpOption) error {
res, err := cli.Delete(ctx, key, opts...)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// Watch 监听
func Watch(key string, opts ...clientv3.OpOption) {
ch := cli.Watch(ctx, key, opts...)
for v := range ch {
for _, val := range v.Events {
helper.PrintJSON(val)
}
}
}
2.8 txn
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
clientv3 "go.etcd.io/etcd/client/v3"
)
// Txn 事务
func Txn(cmp []clientv3.Cmp, success []clientv3.Op, fail []clientv3.Op) error {
txn := cli.Txn(ctx)
for _,cs := range cmp {
txn.If(cs)
}
for _,op := range success {
txn.Then(op)
}
for _,op := range fail {
txn.Else(op)
}
res, err := txn.Commit()
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
2.9 lock
package base
import (
"go.etcd.io/etcd/client/v3/concurrency"
)
// Mutex 分布式锁
func Mutex(ttl int64, pfx string) (*concurrency.Mutex, error) {
res, err := cli.Grant(ctx, ttl)
if err != nil {
return nil, err
}
s, err := concurrency.NewSession(
cli, concurrency.WithContext(ctx), concurrency.WithTTL(int(ttl)), concurrency.WithLease(res.ID),
)
if err != nil {
return nil, err
}
return concurrency.NewMutex(s, pfx), nil
}
2.10 snapshot
package base
import (
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/client/v3/snapshot"
)
// SnapshotSave 生成快照
func SnapshotSave(cfg clientv3.Config, dbPath string) error {
err := snapshot.Save(ctx, nil, cfg, dbPath)
if err != nil {
return err
}
return nil
}
2.11 alarm
package base
import (
"github.com/jormin/etcd-demo/pkg/helper"
clientv3 "go.etcd.io/etcd/client/v3"
)
// AlarmList 获取警报列表
func AlarmList() error {
res, err := cli.AlarmList(ctx)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}
// AlarmDisarm 解除警报
func AlarmDisarm(m *clientv3.AlarmMember) error {
res, err := cli.AlarmDisarm(ctx, m)
if err != nil {
return err
}
helper.PrintJSON(res)
return nil
}