v3_curl_test.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // Copyright 2016 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package e2e
  15. import (
  16. "encoding/json"
  17. "path"
  18. "testing"
  19. pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
  20. "github.com/coreos/etcd/pkg/testutil"
  21. "github.com/grpc-ecosystem/grpc-gateway/runtime"
  22. )
  23. // TODO: remove /v3beta tests in 3.5 release
  24. var apiPrefix = []string{"/v3", "/v3beta"}
  25. func TestV3CurlPutGetNoTLS(t *testing.T) {
  26. for _, p := range apiPrefix {
  27. testCtl(t, testV3CurlPutGet, withApiPrefix(p), withCfg(configNoTLS))
  28. }
  29. }
  30. func TestV3CurlPutGetAutoTLS(t *testing.T) {
  31. for _, p := range apiPrefix {
  32. testCtl(t, testV3CurlPutGet, withApiPrefix(p), withCfg(configAutoTLS))
  33. }
  34. }
  35. func TestV3CurlPutGetAllTLS(t *testing.T) {
  36. for _, p := range apiPrefix {
  37. testCtl(t, testV3CurlPutGet, withApiPrefix(p), withCfg(configTLS))
  38. }
  39. }
  40. func TestV3CurlPutGetPeerTLS(t *testing.T) {
  41. for _, p := range apiPrefix {
  42. testCtl(t, testV3CurlPutGet, withApiPrefix(p), withCfg(configPeerTLS))
  43. }
  44. }
  45. func TestV3CurlPutGetClientTLS(t *testing.T) {
  46. for _, p := range apiPrefix {
  47. testCtl(t, testV3CurlPutGet, withApiPrefix(p), withCfg(configClientTLS))
  48. }
  49. }
  50. func TestV3CurlWatch(t *testing.T) {
  51. for _, p := range apiPrefix {
  52. testCtl(t, testV3CurlWatch, withApiPrefix(p))
  53. }
  54. }
  55. func TestV3CurlTxn(t *testing.T) {
  56. for _, p := range apiPrefix {
  57. testCtl(t, testV3CurlTxn, withApiPrefix(p))
  58. }
  59. }
  60. func TestV3CurlAuth(t *testing.T) {
  61. for _, p := range apiPrefix {
  62. testCtl(t, testV3CurlAuth, withApiPrefix(p))
  63. }
  64. }
  65. func testV3CurlPutGet(cx ctlCtx) {
  66. var (
  67. key = []byte("foo")
  68. value = []byte("bar") // this will be automatically base64-encoded by Go
  69. expectPut = `"revision":"`
  70. expectGet = `"value":"`
  71. )
  72. putData, err := json.Marshal(&pb.PutRequest{
  73. Key: key,
  74. Value: value,
  75. })
  76. if err != nil {
  77. cx.t.Fatal(err)
  78. }
  79. rangeData, err := json.Marshal(&pb.RangeRequest{
  80. Key: key,
  81. })
  82. if err != nil {
  83. cx.t.Fatal(err)
  84. }
  85. p := cx.apiPrefix
  86. if err := cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/put"), value: string(putData), expected: expectPut}); err != nil {
  87. cx.t.Fatalf("failed testV3CurlPutGet put with curl using prefix (%s) (%v)", p, err)
  88. }
  89. if err := cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/range"), value: string(rangeData), expected: expectGet}); err != nil {
  90. cx.t.Fatalf("failed testV3CurlPutGet get with curl using prefix (%s) (%v)", p, err)
  91. }
  92. if cx.cfg.clientTLS == clientTLSAndNonTLS {
  93. if err := cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/range"), value: string(rangeData), expected: expectGet, isTLS: true}); err != nil {
  94. cx.t.Fatalf("failed testV3CurlPutGet get with curl using prefix (%s) (%v)", p, err)
  95. }
  96. }
  97. }
  98. func testV3CurlWatch(cx ctlCtx) {
  99. // store "bar" into "foo"
  100. putreq, err := json.Marshal(&pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")})
  101. if err != nil {
  102. cx.t.Fatal(err)
  103. }
  104. // watch for first update to "foo"
  105. wcr := &pb.WatchCreateRequest{Key: []byte("foo"), StartRevision: 1}
  106. wreq, err := json.Marshal(wcr)
  107. if err != nil {
  108. cx.t.Fatal(err)
  109. }
  110. // marshaling the grpc to json gives:
  111. // "{"RequestUnion":{"CreateRequest":{"key":"Zm9v","start_revision":1}}}"
  112. // but the gprc-gateway expects a different format..
  113. wstr := `{"create_request" : ` + string(wreq) + "}"
  114. p := cx.apiPrefix
  115. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/put"), value: string(putreq), expected: "revision"}); err != nil {
  116. cx.t.Fatalf("failed testV3CurlWatch put with curl using prefix (%s) (%v)", p, err)
  117. }
  118. // expects "bar", timeout after 2 seconds since stream waits forever
  119. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/watch"), value: wstr, expected: `"YmFy"`, timeout: 2}); err != nil {
  120. cx.t.Fatalf("failed testV3CurlWatch watch with curl using prefix (%s) (%v)", p, err)
  121. }
  122. }
  123. func testV3CurlTxn(cx ctlCtx) {
  124. txn := &pb.TxnRequest{
  125. Compare: []*pb.Compare{
  126. {
  127. Key: []byte("foo"),
  128. Result: pb.Compare_EQUAL,
  129. Target: pb.Compare_CREATE,
  130. TargetUnion: &pb.Compare_CreateRevision{CreateRevision: 0},
  131. },
  132. },
  133. Success: []*pb.RequestOp{
  134. {
  135. Request: &pb.RequestOp_RequestPut{
  136. RequestPut: &pb.PutRequest{
  137. Key: []byte("foo"),
  138. Value: []byte("bar"),
  139. },
  140. },
  141. },
  142. },
  143. }
  144. m := &runtime.JSONPb{}
  145. jsonDat, jerr := m.Marshal(txn)
  146. if jerr != nil {
  147. cx.t.Fatal(jerr)
  148. }
  149. expected := `"succeeded":true,"responses":[{"response_put":{"header":{"revision":"2"}}}]`
  150. p := cx.apiPrefix
  151. if err := cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/txn"), value: string(jsonDat), expected: expected}); err != nil {
  152. cx.t.Fatalf("failed testV3CurlTxn txn with curl using prefix (%s) (%v)", p, err)
  153. }
  154. // was crashing etcd server
  155. malformed := `{"compare":[{"result":0,"target":1,"key":"Zm9v","TargetUnion":null}],"success":[{"Request":{"RequestPut":{"key":"Zm9v","value":"YmFy"}}}]}`
  156. if err := cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/txn"), value: malformed, expected: "error"}); err != nil {
  157. cx.t.Fatalf("failed testV3CurlTxn put with curl using prefix (%s) (%v)", p, err)
  158. }
  159. }
  160. func testV3CurlAuth(cx ctlCtx) {
  161. // create root user
  162. userreq, err := json.Marshal(&pb.AuthUserAddRequest{Name: string("root"), Password: string("toor")})
  163. testutil.AssertNil(cx.t, err)
  164. p := cx.apiPrefix
  165. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/auth/user/add"), value: string(userreq), expected: "revision"}); err != nil {
  166. cx.t.Fatalf("failed testV3CurlAuth add user with curl (%v)", err)
  167. }
  168. // create root role
  169. rolereq, err := json.Marshal(&pb.AuthRoleAddRequest{Name: string("root")})
  170. testutil.AssertNil(cx.t, err)
  171. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/auth/role/add"), value: string(rolereq), expected: "revision"}); err != nil {
  172. cx.t.Fatalf("failed testV3CurlAuth create role with curl using prefix (%s) (%v)", p, err)
  173. }
  174. // grant root role
  175. grantrolereq, err := json.Marshal(&pb.AuthUserGrantRoleRequest{User: string("root"), Role: string("root")})
  176. testutil.AssertNil(cx.t, err)
  177. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/auth/user/grant"), value: string(grantrolereq), expected: "revision"}); err != nil {
  178. cx.t.Fatalf("failed testV3CurlAuth grant role with curl using prefix (%s) (%v)", p, err)
  179. }
  180. // enable auth
  181. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/auth/enable"), value: string("{}"), expected: "revision"}); err != nil {
  182. cx.t.Fatalf("failed testV3CurlAuth enable auth with curl using prefix (%s) (%v)", p, err)
  183. }
  184. // put "bar" into "foo"
  185. putreq, err := json.Marshal(&pb.PutRequest{Key: []byte("foo"), Value: []byte("bar")})
  186. testutil.AssertNil(cx.t, err)
  187. // fail put no auth
  188. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/put"), value: string(putreq), expected: "error"}); err != nil {
  189. cx.t.Fatalf("failed testV3CurlAuth no auth put with curl using prefix (%s) (%v)", p, err)
  190. }
  191. // auth request
  192. authreq, err := json.Marshal(&pb.AuthenticateRequest{Name: string("root"), Password: string("toor")})
  193. testutil.AssertNil(cx.t, err)
  194. var (
  195. authHeader string
  196. cmdArgs []string
  197. lineFunc = func(txt string) bool { return true }
  198. )
  199. cmdArgs = cURLPrefixArgs(cx.epc, "POST", cURLReq{endpoint: path.Join(p, "/auth/authenticate"), value: string(authreq)})
  200. proc, err := spawnCmd(cmdArgs)
  201. testutil.AssertNil(cx.t, err)
  202. cURLRes, err := proc.ExpectFunc(lineFunc)
  203. testutil.AssertNil(cx.t, err)
  204. authRes := make(map[string]interface{})
  205. testutil.AssertNil(cx.t, json.Unmarshal([]byte(cURLRes), &authRes))
  206. token, ok := authRes["token"].(string)
  207. if !ok {
  208. cx.t.Fatalf("failed invalid token in authenticate response with curl")
  209. }
  210. authHeader = "Authorization : " + token
  211. // put with auth
  212. if err = cURLPost(cx.epc, cURLReq{endpoint: path.Join(p, "/kv/put"), value: string(putreq), header: authHeader, expected: "revision"}); err != nil {
  213. cx.t.Fatalf("failed testV3CurlAuth auth put with curl using prefix (%s) (%v)", p, err)
  214. }
  215. }