Fix: vela status --endpoint show no IP when only one master node (#5141)

Add fallback if no worker node

check app exist

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 7af0a67dee)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
This commit is contained in:
github-actions[bot]
2022-11-30 10:47:19 +08:00
committed by GitHub
parent c58e3dfea6
commit 353e592391
4 changed files with 151 additions and 39 deletions

View File

@@ -398,20 +398,7 @@ func selectorNodeIP(ctx context.Context, clusterName string, client client.Clien
if len(nodes.Items) == 0 {
return ""
}
var gatewayNode *corev1.Node
var workerNodes []corev1.Node
for i, node := range nodes.Items {
if _, exist := node.Labels[apis.LabelNodeRoleGateway]; exist {
gatewayNode = &nodes.Items[i]
break
} else if _, exist := node.Labels[apis.LabelNodeRoleWorker]; exist {
workerNodes = append(workerNodes, nodes.Items[i])
}
}
if gatewayNode != nil {
return selectGatewayIP([]corev1.Node{*gatewayNode})
}
return selectGatewayIP(workerNodes)
return selectGatewayIP(nodes.Items)
}
// judgeAppProtocol RFC-6335 and http://www.iana.org/assignments/service-names).
@@ -432,11 +419,28 @@ func judgeAppProtocol(port int32) string {
// selectGatewayIP will choose one gateway IP from all nodes, it will pick up external IP first. If there isn't any, it will pick the first node's internal IP.
func selectGatewayIP(nodes []corev1.Node) string {
if len(nodes) == 0 {
var gatewayNode *corev1.Node
var workerNodes []corev1.Node
for i, node := range nodes {
if _, exist := node.Labels[apis.LabelNodeRoleGateway]; exist {
gatewayNode = &nodes[i]
break
} else if _, exist := node.Labels[apis.LabelNodeRoleWorker]; exist {
workerNodes = append(workerNodes, nodes[i])
}
}
var candidates = nodes
if gatewayNode != nil {
candidates = []corev1.Node{*gatewayNode}
} else if len(workerNodes) > 0 {
candidates = workerNodes
}
if len(candidates) == 0 {
return ""
}
var addressMaps = make([]map[corev1.NodeAddressType]string, 0)
for _, node := range nodes {
for _, node := range candidates {
var addressMap = make(map[corev1.NodeAddressType]string)
for _, address := range node.Status.Addresses {
addressMap[address.Type] = address.Address

View File

@@ -274,47 +274,108 @@ var _ = Describe("Test query endpoints", func() {
})
It("Test select gateway IP", func() {
node1 := corev1.Node{
masterNode := corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-with-external-ip",
Name: "node-1",
Labels: map[string]string{
"node-role.kubernetes.io/master": "true",
},
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeExternalIP, Address: "node1-external-ip"},
{Type: corev1.NodeInternalIP, Address: "node1-internal-ip"},
{
Type: corev1.NodeInternalIP,
Address: "node1-internal-ip",
},
},
},
}
node2 := corev1.Node{
workerNode1 := corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-without-external-ip",
Name: "node-2",
Labels: map[string]string{
"node-role.kubernetes.io/worker": "true",
},
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "node2-internal-ip"},
{
Type: corev1.NodeInternalIP,
Address: "node2-internal-ip",
},
{
Type: corev1.NodeExternalIP,
Address: "node2-external-ip",
},
},
},
}
testCases := []struct {
workerNode2 := corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-3",
Labels: map[string]string{
"node-role.kubernetes.io/worker": "true",
},
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{
Type: corev1.NodeInternalIP,
Address: "node3-internal-ip",
},
},
},
}
gatewayNode := corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-4",
Labels: map[string]string{
"node-role.kubernetes.io/gateway": "true",
},
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{
Type: corev1.NodeInternalIP,
Address: "node4-internal-ip",
},
{
Type: corev1.NodeExternalIP,
Address: "node4-external-ip",
},
},
},
}
testCase := []struct {
note string
nodes []corev1.Node
wantIP string
}{
{
nodes: []corev1.Node{node1, node2},
wantIP: "node1-external-ip",
note: "only master node",
nodes: []corev1.Node{masterNode},
wantIP: "node1-internal-ip",
},
{
nodes: []corev1.Node{node2},
wantIP: "node2-internal-ip",
note: "with worker node, select external ip first",
nodes: []corev1.Node{masterNode, workerNode1},
wantIP: "node2-external-ip",
},
{
nodes: []corev1.Node{},
wantIP: "",
note: "with worker node, select worker's internal ip",
nodes: []corev1.Node{masterNode, workerNode2},
wantIP: "node3-internal-ip",
},
{
note: "with gateway node, gateway node first",
nodes: []corev1.Node{masterNode, workerNode1, workerNode1, gatewayNode},
wantIP: "node4-external-ip",
},
}
for _, tc := range testCases {
gotIP := selectGatewayIP(tc.nodes)
Expect(gotIP).Should(BeEquivalentTo(tc.wantIP))
for _, tc := range testCase {
By(tc.note)
ip := selectGatewayIP(tc.nodes)
Expect(ip).Should(Equal(tc.wantIP))
}
})
})

View File

@@ -19,7 +19,7 @@ package query
import (
"context"
"fmt"
"io/ioutil"
"os"
"time"
. "github.com/onsi/ginkgo"
@@ -929,7 +929,7 @@ options: {
}
var objects []client.Object
for _, resource := range resources {
data, err := ioutil.ReadFile(resource)
data, err := os.ReadFile(resource)
Expect(err).Should(BeNil())
var route unstructured.Unstructured
err = yaml.Unmarshal(data, &route)
@@ -942,6 +942,46 @@ options: {
Expect(err).Should(BeNil())
}
// Prepare nodes in test environment
masterNode := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-1",
Labels: map[string]string{
"node-role.kubernetes.io/master": "true",
},
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{
Type: corev1.NodeInternalIP,
Address: "internal-ip-1",
},
},
},
}
workerNode := &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-2",
Labels: map[string]string{
"node-role.kubernetes.io/worker": "true",
},
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{
Type: corev1.NodeInternalIP,
Address: "internal-ip-2",
},
{
Type: corev1.NodeExternalIP,
Address: "external-ip-2",
},
},
},
}
Expect(k8sClient.Create(ctx, masterNode)).Should(BeNil())
Expect(k8sClient.Create(ctx, workerNode)).Should(BeNil())
opt := `app: {
name: "endpoints-app"
namespace: "default"
@@ -960,6 +1000,7 @@ options: {
err = pr.CollectServiceEndpoints(logCtx, nil, v, nil)
Expect(err).Should(BeNil())
gatewayIP := selectorNodeIP(ctx, "", k8sClient)
Expect(gatewayIP).Should(Equal("external-ip-2"))
urls := []string{
"http://ingress.domain",
"https://ingress.domain.https",

View File

@@ -143,8 +143,18 @@ func NewAppStatusCommand(c common.Args, order string, ioStreams cmdutil.IOStream
}
return printAppPods(appName, namespace, f, c)
}
newClient, err := c.GetClient()
if err != nil {
return err
}
showEndpoints, err := cmd.Flags().GetBool("endpoint")
if showEndpoints && err == nil {
_, err := loadRemoteApplication(newClient, namespace, appName)
if err != nil {
return err
}
component, _ := cmd.Flags().GetString("component")
cluster, _ := cmd.Flags().GetString("cluster")
f := Filter{
@@ -153,10 +163,6 @@ func NewAppStatusCommand(c common.Args, order string, ioStreams cmdutil.IOStream
}
return printAppEndpoints(ctx, appName, namespace, f, c, false)
}
newClient, err := c.GetClient()
if err != nil {
return err
}
if outputFormat != "" {
return printRawApplication(context.Background(), c, outputFormat, cmd.OutOrStdout(), namespace, appName)
}