本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
3.5KB

  1. package couchbase
  2. /*
  3. The goal here is to map a hostname:port combination to another hostname:port
  4. combination. The original hostname:port gives the name and regular KV port
  5. of a couchbase server. We want to determine the corresponding SSL KV port.
  6. To do this, we have a pool services structure, as obtained from
  7. the /pools/default/nodeServices API.
  8. For a fully configured two-node system, the structure may look like this:
  9. {"rev":32,"nodesExt":[
  10. {"services":{"mgmt":8091,"mgmtSSL":18091,"fts":8094,"ftsSSL":18094,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211},"hostname":"172.23.123.101"},
  11. {"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211,"n1ql":8093,"n1qlSSL":18093},"thisNode":true,"hostname":"172.23.123.102"}]}
  12. In this case, note the "hostname" fields, and the "kv" and "kvSSL" fields.
  13. For a single-node system, perhaps brought up for testing, the structure may look like this:
  14. {"rev":66,"nodesExt":[
  15. {"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"kv":11210,"kvSSL":11207,"capi":8092,"capiSSL":18092,"projector":9999,"n1ql":8093,"n1qlSSL":18093},"thisNode":true}],"clusterCapabilitiesVer":[1,0],"clusterCapabilities":{"n1ql":["enhancedPreparedStatements"]}}
  16. Here, note that there is only a single entry in the "nodeExt" array and that it does not have a "hostname" field.
  17. We will assume that either hostname fields are present, or there is only a single node.
  18. */
  19. import (
  20. "encoding/json"
  21. "fmt"
  22. "strconv"
  23. "strings"
  24. )
  25. func ParsePoolServices(jsonInput string) (*PoolServices, error) {
  26. ps := &PoolServices{}
  27. err := json.Unmarshal([]byte(jsonInput), ps)
  28. return ps, err
  29. }
  30. func MapKVtoSSL(hostport string, ps *PoolServices) (string, error) {
  31. colonIndex := strings.LastIndex(hostport, ":")
  32. if colonIndex < 0 {
  33. return "", fmt.Errorf("Unable to find host/port separator in %s", hostport)
  34. }
  35. host := hostport[0:colonIndex]
  36. port := hostport[colonIndex+1:]
  37. portInt, err := strconv.Atoi(port)
  38. if err != nil {
  39. return "", fmt.Errorf("Unable to parse host/port combination %s: %v", hostport, err)
  40. }
  41. var ns *NodeServices
  42. if len(ps.NodesExt) == 1 {
  43. ns = &(ps.NodesExt[0])
  44. } else {
  45. for i := range ps.NodesExt {
  46. hostname := ps.NodesExt[i].Hostname
  47. if len(hostname) == 0 {
  48. // in case of missing hostname, check for 127.0.0.1
  49. hostname = "127.0.0.1"
  50. }
  51. if hostname == host {
  52. ns = &(ps.NodesExt[i])
  53. break
  54. }
  55. }
  56. }
  57. if ns == nil {
  58. return "", fmt.Errorf("Unable to parse host/port combination %s: no matching node found among %d", hostport, len(ps.NodesExt))
  59. }
  60. kv, found := ns.Services["kv"]
  61. if !found {
  62. return "", fmt.Errorf("Unable to map host/port combination %s: target host has no kv port listed", hostport)
  63. }
  64. kvSSL, found := ns.Services["kvSSL"]
  65. if !found {
  66. return "", fmt.Errorf("Unable to map host/port combination %s: target host has no kvSSL port listed", hostport)
  67. }
  68. if portInt != kv {
  69. return "", fmt.Errorf("Unable to map hostport combination %s: expected port %d but found %d", hostport, portInt, kv)
  70. }
  71. return fmt.Sprintf("%s:%d", host, kvSSL), nil
  72. }
上海开阖软件有限公司 沪ICP备12045867号-1