member_commands.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package command
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "strings"
  7. "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/go.net/context"
  8. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/codegangsta/cli"
  9. "github.com/coreos/etcd/client"
  10. )
  11. func NewMemberCommand() cli.Command {
  12. return cli.Command{
  13. Name: "member",
  14. Usage: "member add, remove and list subcommands",
  15. Subcommands: []cli.Command{
  16. cli.Command{
  17. Name: "list",
  18. Usage: "enumerate existing cluster members",
  19. Action: actionMemberList,
  20. },
  21. cli.Command{
  22. Name: "add",
  23. Usage: "add a new member to the etcd cluster",
  24. Action: actionMemberAdd,
  25. },
  26. cli.Command{
  27. Name: "remove",
  28. Usage: "remove an existing member from the etcd cluster",
  29. Action: actionMemberRemove,
  30. },
  31. },
  32. }
  33. }
  34. func mustNewMembersAPI(c *cli.Context) client.MembersAPI {
  35. peers := getPeersFlagValue(c)
  36. for i, p := range peers {
  37. if !strings.HasPrefix(p, "http") && !strings.HasPrefix(p, "https") {
  38. peers[i] = fmt.Sprintf("http://%s", p)
  39. }
  40. }
  41. hc, err := client.NewHTTPClient(&http.Transport{}, peers)
  42. if err != nil {
  43. fmt.Fprintln(os.Stderr, err.Error())
  44. os.Exit(1)
  45. }
  46. if !c.GlobalBool("no-sync") {
  47. ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
  48. err := hc.Sync(ctx)
  49. cancel()
  50. if err != nil {
  51. fmt.Fprintln(os.Stderr, err.Error())
  52. os.Exit(1)
  53. }
  54. }
  55. return client.NewMembersAPI(hc)
  56. }
  57. func actionMemberList(c *cli.Context) {
  58. if len(c.Args()) != 0 {
  59. fmt.Fprintln(os.Stderr, "No arguments accepted")
  60. os.Exit(1)
  61. }
  62. mAPI := mustNewMembersAPI(c)
  63. ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
  64. members, err := mAPI.List(ctx)
  65. cancel()
  66. if err != nil {
  67. fmt.Fprintln(os.Stderr, err.Error())
  68. os.Exit(1)
  69. }
  70. for _, m := range members {
  71. fmt.Printf("%s: name=%s peerURLs=%s clientURLs=%s\n", m.ID, m.Name, strings.Join(m.PeerURLs, ","), strings.Join(m.ClientURLs, ","))
  72. }
  73. }
  74. func actionMemberAdd(c *cli.Context) {
  75. args := c.Args()
  76. if len(args) != 2 {
  77. fmt.Fprintln(os.Stderr, "Provide a name and a single member peerURL")
  78. os.Exit(1)
  79. }
  80. mAPI := mustNewMembersAPI(c)
  81. url := args[1]
  82. ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
  83. m, err := mAPI.Add(ctx, url)
  84. cancel()
  85. if err != nil {
  86. fmt.Fprintln(os.Stderr, err.Error())
  87. os.Exit(1)
  88. }
  89. newID := m.ID
  90. newName := args[0]
  91. fmt.Printf("Added member named %s with ID %s to cluster\n", newName, newID)
  92. ctx, cancel = context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
  93. members, err := mAPI.List(ctx)
  94. cancel()
  95. if err != nil {
  96. fmt.Fprintln(os.Stderr, err.Error())
  97. os.Exit(1)
  98. }
  99. conf := []string{}
  100. for _, m := range members {
  101. for _, u := range m.PeerURLs {
  102. n := m.Name
  103. if m.ID == newID {
  104. n = newName
  105. }
  106. conf = append(conf, fmt.Sprintf("%s=%s", n, u))
  107. }
  108. }
  109. fmt.Print("\n")
  110. fmt.Printf("ETCD_NAME=%q\n", newName)
  111. fmt.Printf("ETCD_INITIAL_CLUSTER=%q\n", strings.Join(conf, ","))
  112. fmt.Printf("ETCD_INITIAL_CLUSTER_STATE=\"existing\"\n")
  113. }
  114. func actionMemberRemove(c *cli.Context) {
  115. args := c.Args()
  116. if len(args) != 1 {
  117. fmt.Fprintln(os.Stderr, "Provide a single member ID")
  118. os.Exit(1)
  119. }
  120. mAPI := mustNewMembersAPI(c)
  121. mID := args[0]
  122. ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
  123. err := mAPI.Remove(ctx, mID)
  124. cancel()
  125. if err != nil {
  126. fmt.Fprintln(os.Stderr, err.Error())
  127. os.Exit(1)
  128. }
  129. fmt.Printf("Removed member %s from cluster\n", mID)
  130. }