You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by zh...@apache.org on 2022/08/17 09:55:32 UTC
[apisix-ingress-controller] branch v1.5.0 updated: fix: nodes convert failed (#1222) (#1250)
This is an automated email from the ASF dual-hosted git repository.
zhangjintao pushed a commit to branch v1.5.0
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/v1.5.0 by this push:
new ca063cdf fix: nodes convert failed (#1222) (#1250)
ca063cdf is described below
commit ca063cdfd400f6bd54421dd3168ebb4d42266fd8
Author: Jintao Zhang <zh...@gmail.com>
AuthorDate: Wed Aug 17 17:55:27 2022 +0800
fix: nodes convert failed (#1222) (#1250)
Co-authored-by: Xin Rong <ro...@api7.ai>
---
pkg/apisix/resource_test.go | 45 ++++++++++++++++++++++++++++++++++++++++++++
pkg/types/apisix/v1/types.go | 43 ++++++++++++++++++++++++++++++++++++++----
2 files changed, 84 insertions(+), 4 deletions(-)
diff --git a/pkg/apisix/resource_test.go b/pkg/apisix/resource_test.go
index 2c969960..528f801d 100644
--- a/pkg/apisix/resource_test.go
+++ b/pkg/apisix/resource_test.go
@@ -78,6 +78,51 @@ func TestItemConvertRoute(t *testing.T) {
assert.Equal(t, r.Name, "unknown")
}
+func TestItemConvertUpstream(t *testing.T) {
+ ite := &item{
+ Key: "/apisix/upstreams/419655639963271872",
+ Value: json.RawMessage(`{ "nodes":{"httpbin.org:80":1, "foo.com:8080": 2}}`),
+ }
+ ups, err := ite.upstream()
+ assert.Nil(t, err)
+ assert.Len(t, ups.Nodes, 2)
+ assert.Equal(t, ups.Nodes[0], v1.UpstreamNode{Host: "httpbin.org", Port: 80, Weight: 1})
+ assert.Equal(t, ups.Nodes[1], v1.UpstreamNode{Host: "foo.com", Port: 8080, Weight: 2})
+
+ ite = &item{
+ Key: "/apisix/upstreams/419655639963271872",
+ Value: json.RawMessage(`
+{
+ "id": "419655639963271872",
+ "nodes": [
+ {
+ "host": "httpbin.org",
+ "port": 80,
+ "weight": 1
+ },
+ {
+ "host": "httpbin.com",
+ "port": 8080,
+ "weight": 1
+ }
+ ]
+}`),
+ }
+ ups, err = ite.upstream()
+ assert.Nil(t, err)
+ assert.Len(t, ups.Nodes, 2)
+ assert.Equal(t, ups.Nodes[0], v1.UpstreamNode{Host: "httpbin.org", Port: 80, Weight: 1})
+ assert.Equal(t, ups.Nodes[1], v1.UpstreamNode{Host: "httpbin.com", Port: 8080, Weight: 1})
+
+ ite = &item{
+ Key: "/apisix/upstreams/419655639963271872",
+ Value: json.RawMessage(`{ "id":"419655639963271872" }`),
+ }
+ ups, err = ite.upstream()
+ assert.Nil(t, err)
+ assert.Len(t, ups.Nodes, 0)
+}
+
func TestRouteVarsUnmarshalJSONCompatibility(t *testing.T) {
var route v1.Route
data := `{"vars":{}}`
diff --git a/pkg/types/apisix/v1/types.go b/pkg/types/apisix/v1/types.go
index 3da9d462..8ffcd0d3 100644
--- a/pkg/types/apisix/v1/types.go
+++ b/pkg/types/apisix/v1/types.go
@@ -18,6 +18,7 @@ import (
"bytes"
"encoding/json"
"errors"
+ "fmt"
"strconv"
"strings"
"time"
@@ -216,14 +217,22 @@ type UpstreamNodes []UpstreamNode
// and by default empty array will be encoded as '{}'.
// We have to maintain the compatibility.
func (n *UpstreamNodes) UnmarshalJSON(p []byte) error {
+ var data []UpstreamNode
if p[0] == '{' {
- if len(p) != 2 {
- return errors.New("unexpected non-empty object")
+ value := map[string]float64{}
+ if err := json.Unmarshal(p, &value); err != nil {
+ return err
+ }
+ for k, v := range value {
+ node, err := mapKV2Node(k, v)
+ if err != nil {
+ return err
+ }
+ data = append(data, *node)
}
- *n = UpstreamNodes{}
+ *n = data
return nil
}
- var data []UpstreamNode
if err := json.Unmarshal(p, &data); err != nil {
return err
}
@@ -231,6 +240,32 @@ func (n *UpstreamNodes) UnmarshalJSON(p []byte) error {
return nil
}
+func mapKV2Node(key string, val float64) (*UpstreamNode, error) {
+ hp := strings.Split(key, ":")
+ host := hp[0]
+ // according to APISIX upstream nodes policy, port is required
+ port := "80"
+
+ if len(hp) > 2 {
+ return nil, errors.New("invalid upstream node")
+ } else if len(hp) == 2 {
+ port = hp[1]
+ }
+
+ portInt, err := strconv.Atoi(port)
+ if err != nil {
+ return nil, fmt.Errorf("parse port to int fail: %s", err.Error())
+ }
+
+ node := &UpstreamNode{
+ Host: host,
+ Port: portInt,
+ Weight: int(val),
+ }
+
+ return node, nil
+}
+
// UpstreamNode is the node in upstream
// +k8s:deepcopy-gen=true
type UpstreamNode struct {