mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Merge pull request #51173 from liggitt/role-printers
Automatic merge from submit-queue (batch tested with PRs 51054, 51101, 50031, 51296, 51173) Print multiple node roles, remove kubeadm-specific annotation from kubectl related to #50010 Follow up to https://github.com/kubernetes/kubernetes/pull/50438 that removes the kubeadm-specific label, makes kubectl role-agnostic, and outputs multiple roles if present
This commit is contained in:
commit
c241cbe44d
@ -2470,7 +2470,11 @@ func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events
|
|||||||
return tabbedString(func(out io.Writer) error {
|
return tabbedString(func(out io.Writer) error {
|
||||||
w := NewPrefixWriter(out)
|
w := NewPrefixWriter(out)
|
||||||
w.Write(LEVEL_0, "Name:\t%s\n", node.Name)
|
w.Write(LEVEL_0, "Name:\t%s\n", node.Name)
|
||||||
w.Write(LEVEL_0, "Role:\t%s\n", findNodeRole(node))
|
if roles := findNodeRoles(node); len(roles) > 0 {
|
||||||
|
w.Write(LEVEL_0, "Roles:\t%s\n", strings.Join(roles, ","))
|
||||||
|
} else {
|
||||||
|
w.Write(LEVEL_0, "Roles:\t%s\n", "<none>")
|
||||||
|
}
|
||||||
printLabelsMultiline(w, "Labels", node.Labels)
|
printLabelsMultiline(w, "Labels", node.Labels)
|
||||||
printAnnotationsMultiline(w, "Annotations", node.Annotations)
|
printAnnotationsMultiline(w, "Annotations", node.Annotations)
|
||||||
printNodeTaintsMultiline(w, "Taints", node.Spec.Taints)
|
printNodeTaintsMultiline(w, "Taints", node.Spec.Taints)
|
||||||
|
@ -62,16 +62,12 @@ import (
|
|||||||
const (
|
const (
|
||||||
loadBalancerWidth = 16
|
loadBalancerWidth = 16
|
||||||
|
|
||||||
// LabelNodeRoleMaster specifies that a node is a master
|
// labelNodeRolePrefix is a label prefix for node roles
|
||||||
// It's copied over to here until it's merged in core: https://github.com/kubernetes/kubernetes/pull/39112
|
// It's copied over to here until it's merged in core: https://github.com/kubernetes/kubernetes/pull/39112
|
||||||
LabelNodeRoleMaster = "node-role.kubernetes.io/master"
|
labelNodeRolePrefix = "node-role.kubernetes.io/"
|
||||||
|
|
||||||
// NodeLabelRole specifies the role of a node
|
// nodeLabelRole specifies the role of a node
|
||||||
NodeLabelRole = "kubernetes.io/role"
|
nodeLabelRole = "kubernetes.io/role"
|
||||||
|
|
||||||
// NodeLabelKubeadmAlphaRole is a label that kubeadm applies to a Node as a hint that it has a particular purpose.
|
|
||||||
// Use of NodeLabelRole is preferred.
|
|
||||||
NodeLabelKubeadmAlphaRole = "kubeadm.alpha.kubernetes.io/role"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddHandlers adds print handlers for default Kubernetes types dealing with internal versions.
|
// AddHandlers adds print handlers for default Kubernetes types dealing with internal versions.
|
||||||
@ -221,6 +217,7 @@ func AddHandlers(h printers.PrintHandler) {
|
|||||||
nodeColumnDefinitions := []metav1alpha1.TableColumnDefinition{
|
nodeColumnDefinitions := []metav1alpha1.TableColumnDefinition{
|
||||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||||
{Name: "Status", Type: "string", Description: "The status of the node"},
|
{Name: "Status", Type: "string", Description: "The status of the node"},
|
||||||
|
{Name: "Roles", Type: "string", Description: "The roles of the node"},
|
||||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||||
{Name: "Version", Type: "string", Description: apiv1.NodeSystemInfo{}.SwaggerDoc()["kubeletVersion"]},
|
{Name: "Version", Type: "string", Description: apiv1.NodeSystemInfo{}.SwaggerDoc()["kubeletVersion"]},
|
||||||
{Name: "External-IP", Type: "string", Priority: 1, Description: apiv1.NodeStatus{}.SwaggerDoc()["addresses"]},
|
{Name: "External-IP", Type: "string", Priority: 1, Description: apiv1.NodeStatus{}.SwaggerDoc()["addresses"]},
|
||||||
@ -1167,12 +1164,13 @@ func printNode(obj *api.Node, options printers.PrintOptions) ([]metav1alpha1.Tab
|
|||||||
if obj.Spec.Unschedulable {
|
if obj.Spec.Unschedulable {
|
||||||
status = append(status, "SchedulingDisabled")
|
status = append(status, "SchedulingDisabled")
|
||||||
}
|
}
|
||||||
role := findNodeRole(obj)
|
|
||||||
if role != "" {
|
roles := strings.Join(findNodeRoles(obj), ",")
|
||||||
status = append(status, role)
|
if len(roles) == 0 {
|
||||||
|
roles = "<none>"
|
||||||
}
|
}
|
||||||
|
|
||||||
row.Cells = append(row.Cells, obj.Name, strings.Join(status, ","), translateTimestamp(obj.CreationTimestamp), obj.Status.NodeInfo.KubeletVersion)
|
row.Cells = append(row.Cells, obj.Name, strings.Join(status, ","), roles, translateTimestamp(obj.CreationTimestamp), obj.Status.NodeInfo.KubeletVersion)
|
||||||
if options.Wide {
|
if options.Wide {
|
||||||
osImage, kernelVersion, crVersion := obj.Status.NodeInfo.OSImage, obj.Status.NodeInfo.KernelVersion, obj.Status.NodeInfo.ContainerRuntimeVersion
|
osImage, kernelVersion, crVersion := obj.Status.NodeInfo.OSImage, obj.Status.NodeInfo.KernelVersion, obj.Status.NodeInfo.ContainerRuntimeVersion
|
||||||
if osImage == "" {
|
if osImage == "" {
|
||||||
@ -1201,22 +1199,24 @@ func getNodeExternalIP(node *api.Node) string {
|
|||||||
return "<none>"
|
return "<none>"
|
||||||
}
|
}
|
||||||
|
|
||||||
// findNodeRole returns the role of a given node, or "" if none found.
|
// findNodeRoles returns the roles of a given node.
|
||||||
// The role is determined by looking in order for:
|
// The roles are determined by looking for:
|
||||||
// * a node-role.kubernetes.io/master label
|
// * a node-role.kubernetes.io/<role>="" label
|
||||||
// * a kubernetes.io/role label
|
// * a kubernetes.io/role="<role>" label
|
||||||
// * a kubeadm.alpha.kubernetes.io/role label
|
func findNodeRoles(node *api.Node) []string {
|
||||||
func findNodeRole(node *api.Node) string {
|
roles := sets.NewString()
|
||||||
if _, ok := node.Labels[LabelNodeRoleMaster]; ok {
|
for k, v := range node.Labels {
|
||||||
return "Master"
|
switch {
|
||||||
|
case strings.HasPrefix(k, labelNodeRolePrefix):
|
||||||
|
if role := strings.TrimPrefix(k, labelNodeRolePrefix); len(role) > 0 {
|
||||||
|
roles.Insert(role)
|
||||||
}
|
}
|
||||||
if role := node.Labels[NodeLabelRole]; role != "" {
|
|
||||||
return strings.Title(role)
|
case k == nodeLabelRole && v != "":
|
||||||
|
roles.Insert(v)
|
||||||
}
|
}
|
||||||
if role := node.Labels[NodeLabelKubeadmAlphaRole]; role != "" {
|
|
||||||
return strings.Title(role)
|
|
||||||
}
|
}
|
||||||
return ""
|
return roles.List()
|
||||||
}
|
}
|
||||||
|
|
||||||
func printNodeList(list *api.NodeList, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
|
func printNodeList(list *api.NodeList, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
|
||||||
|
@ -825,34 +825,6 @@ func TestPrintNodeStatus(t *testing.T) {
|
|||||||
},
|
},
|
||||||
status: "Unknown,SchedulingDisabled",
|
status: "Unknown,SchedulingDisabled",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
node: api.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo10",
|
|
||||||
Labels: map[string]string{"node-role.kubernetes.io/master": "", "kubernetes.io/role": "node", "kubeadm.alpha.kubernetes.io/role": "node"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
status: "Unknown,Master",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: api.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo11",
|
|
||||||
Labels: map[string]string{"kubernetes.io/role": "node", "kubeadm.alpha.kubernetes.io/role": "node"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
status: "Unknown,Node",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
node: api.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo12",
|
|
||||||
Labels: map[string]string{"kubeadm.alpha.kubernetes.io/role": "node"},
|
|
||||||
},
|
|
||||||
Status: api.NodeStatus{Conditions: []api.NodeCondition{{Type: api.NodeReady, Status: api.ConditionTrue}}},
|
|
||||||
},
|
|
||||||
status: "Ready,Node",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
@ -867,6 +839,51 @@ func TestPrintNodeStatus(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintNodeRole(t *testing.T) {
|
||||||
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
|
AddHandlers(printer)
|
||||||
|
table := []struct {
|
||||||
|
node api.Node
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
node: api.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "foo9"},
|
||||||
|
},
|
||||||
|
expected: "<none>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: api.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "foo10",
|
||||||
|
Labels: map[string]string{"node-role.kubernetes.io/master": "", "node-role.kubernetes.io/proxy": "", "kubernetes.io/role": "node"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "master,node,proxy",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node: api.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "foo11",
|
||||||
|
Labels: map[string]string{"kubernetes.io/role": "node"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: "node",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range table {
|
||||||
|
buffer := &bytes.Buffer{}
|
||||||
|
err := printer.PrintObj(&test.node, buffer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("An error occurred printing Node: %#v", err)
|
||||||
|
}
|
||||||
|
if !contains(strings.Fields(buffer.String()), test.expected) {
|
||||||
|
t.Fatalf("Expect printing node %s with role %#v, got: %#v", test.node.Name, test.expected, buffer.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPrintNodeOSImage(t *testing.T) {
|
func TestPrintNodeOSImage(t *testing.T) {
|
||||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
|
Loading…
Reference in New Issue
Block a user