config.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package config
  2. import (
  3. "context"
  4. "errors"
  5. clientv3 "go.etcd.io/etcd/client/v3"
  6. "path/filepath"
  7. "strings"
  8. "github.com/go-kratos/kratos/v2/config"
  9. )
  10. // Option is etcd config option.
  11. type Option func(o *options)
  12. type options struct {
  13. ctx context.Context
  14. path string
  15. prefix bool
  16. }
  17. // WithContext with registry context.
  18. func WithContext(ctx context.Context) Option {
  19. return func(o *options) {
  20. o.ctx = ctx
  21. }
  22. }
  23. // WithPath is config path
  24. func WithPath(p string) Option {
  25. return func(o *options) {
  26. o.path = p
  27. }
  28. }
  29. // WithPrefix is config prefix
  30. func WithPrefix(prefix bool) Option {
  31. return func(o *options) {
  32. o.prefix = prefix
  33. }
  34. }
  35. type source struct {
  36. client *clientv3.Client
  37. options *options
  38. }
  39. func New(client *clientv3.Client, opts ...Option) (config.Source, error) {
  40. options := &options{
  41. ctx: context.Background(),
  42. path: "",
  43. prefix: false,
  44. }
  45. for _, opt := range opts {
  46. opt(options)
  47. }
  48. if options.path == "" {
  49. return nil, errors.New("path invalid")
  50. }
  51. return &source{
  52. client: client,
  53. options: options,
  54. }, nil
  55. }
  56. // Load return the config values
  57. func (s *source) Load() ([]*config.KeyValue, error) {
  58. var opts []clientv3.OpOption
  59. if s.options.prefix {
  60. opts = append(opts, clientv3.WithPrefix())
  61. }
  62. rsp, err := s.client.Get(s.options.ctx, s.options.path, opts...)
  63. if err != nil {
  64. return nil, err
  65. }
  66. kvs := make([]*config.KeyValue, 0, len(rsp.Kvs))
  67. for _, item := range rsp.Kvs {
  68. k := string(item.Key)
  69. kvs = append(kvs, &config.KeyValue{
  70. Key: k,
  71. Value: item.Value,
  72. Format: strings.TrimPrefix(filepath.Ext(k), "."),
  73. })
  74. }
  75. return kvs, nil
  76. }
  77. // Watch return the watcher
  78. func (s *source) Watch() (config.Watcher, error) {
  79. return newWatcher(s), nil
  80. }