mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Adding kubectl support for EndpointSlice
This commit is contained in:
parent
41049fdf4b
commit
ab1943e00b
@ -21,6 +21,7 @@ go_test(
|
|||||||
"//pkg/apis/batch:go_default_library",
|
"//pkg/apis/batch:go_default_library",
|
||||||
"//pkg/apis/coordination:go_default_library",
|
"//pkg/apis/coordination:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
|
"//pkg/apis/discovery:go_default_library",
|
||||||
"//pkg/apis/networking:go_default_library",
|
"//pkg/apis/networking:go_default_library",
|
||||||
"//pkg/apis/node:go_default_library",
|
"//pkg/apis/node:go_default_library",
|
||||||
"//pkg/apis/policy:go_default_library",
|
"//pkg/apis/policy:go_default_library",
|
||||||
@ -40,6 +41,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||||
"//staging/src/k8s.io/cli-runtime/pkg/printers:go_default_library",
|
"//staging/src/k8s.io/cli-runtime/pkg/printers:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -472,9 +472,10 @@ func AddHandlers(h printers.PrintHandler) {
|
|||||||
|
|
||||||
endpointSliceColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
endpointSliceColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||||
{Name: "Ports", Type: "string", Description: discoveryv1alpha1.EndpointSlice{}.SwaggerDoc()["ports"]},
|
|
||||||
{Name: "AddressType", Type: "string", Description: discoveryv1alpha1.EndpointSlice{}.SwaggerDoc()["addressType"]},
|
{Name: "AddressType", Type: "string", Description: discoveryv1alpha1.EndpointSlice{}.SwaggerDoc()["addressType"]},
|
||||||
|
{Name: "Ports", Type: "string", Description: discoveryv1alpha1.EndpointSlice{}.SwaggerDoc()["ports"]},
|
||||||
{Name: "Endpoints", Type: "string", Description: discoveryv1alpha1.EndpointSlice{}.SwaggerDoc()["endpoints"]},
|
{Name: "Endpoints", Type: "string", Description: discoveryv1alpha1.EndpointSlice{}.SwaggerDoc()["endpoints"]},
|
||||||
|
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||||
}
|
}
|
||||||
h.TableHandler(endpointSliceColumnDefinitions, printEndpointSlice)
|
h.TableHandler(endpointSliceColumnDefinitions, printEndpointSlice)
|
||||||
h.TableHandler(endpointSliceColumnDefinitions, printEndpointSliceList)
|
h.TableHandler(endpointSliceColumnDefinitions, printEndpointSliceList)
|
||||||
@ -529,6 +530,57 @@ func formatEndpoints(endpoints *api.Endpoints, ports sets.String) string {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatDiscoveryPorts(ports []discovery.EndpointPort) string {
|
||||||
|
list := []string{}
|
||||||
|
max := 3
|
||||||
|
more := false
|
||||||
|
count := 0
|
||||||
|
for _, port := range ports {
|
||||||
|
if len(list) < max {
|
||||||
|
portNum := "*"
|
||||||
|
if port.Port != nil {
|
||||||
|
portNum = strconv.Itoa(int(*port.Port))
|
||||||
|
} else if port.Name != nil {
|
||||||
|
portNum = *port.Name
|
||||||
|
}
|
||||||
|
list = append(list, portNum)
|
||||||
|
} else if len(list) == max {
|
||||||
|
more = true
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
return listWithMoreString(list, more, count, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatDiscoveryEndpoints(endpoints []discovery.Endpoint) string {
|
||||||
|
list := []string{}
|
||||||
|
max := 3
|
||||||
|
more := false
|
||||||
|
count := 0
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
for _, address := range endpoint.Addresses {
|
||||||
|
if len(list) < max {
|
||||||
|
list = append(list, address)
|
||||||
|
} else if len(list) == max {
|
||||||
|
more = true
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return listWithMoreString(list, more, count, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listWithMoreString(list []string, more bool, count, max int) string {
|
||||||
|
ret := strings.Join(list, ",")
|
||||||
|
if more {
|
||||||
|
return fmt.Sprintf("%s + %d more...", ret, count-max)
|
||||||
|
}
|
||||||
|
if ret == "" {
|
||||||
|
ret = "<unset>"
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
// translateTimestampSince returns the elapsed time since timestamp in
|
// translateTimestampSince returns the elapsed time since timestamp in
|
||||||
// human-readable approximation.
|
// human-readable approximation.
|
||||||
func translateTimestampSince(timestamp metav1.Time) string {
|
func translateTimestampSince(timestamp metav1.Time) string {
|
||||||
@ -1118,7 +1170,11 @@ func printEndpointSlice(obj *discovery.EndpointSlice, options printers.GenerateO
|
|||||||
row := metav1beta1.TableRow{
|
row := metav1beta1.TableRow{
|
||||||
Object: runtime.RawExtension{Object: obj},
|
Object: runtime.RawExtension{Object: obj},
|
||||||
}
|
}
|
||||||
row.Cells = append(row.Cells, obj.Name, obj.Ports, obj.AddressType, obj.Endpoints)
|
addressType := "<unset>"
|
||||||
|
if obj.AddressType != nil {
|
||||||
|
addressType = string(*obj.AddressType)
|
||||||
|
}
|
||||||
|
row.Cells = append(row.Cells, obj.Name, addressType, formatDiscoveryPorts(obj.Ports), formatDiscoveryEndpoints(obj.Endpoints), translateTimestampSince(obj.CreationTimestamp))
|
||||||
return []metav1beta1.TableRow{row}, nil
|
return []metav1beta1.TableRow{row}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,14 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/batch"
|
"k8s.io/kubernetes/pkg/apis/batch"
|
||||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/discovery"
|
||||||
"k8s.io/kubernetes/pkg/apis/networking"
|
"k8s.io/kubernetes/pkg/apis/networking"
|
||||||
nodeapi "k8s.io/kubernetes/pkg/apis/node"
|
nodeapi "k8s.io/kubernetes/pkg/apis/node"
|
||||||
"k8s.io/kubernetes/pkg/apis/policy"
|
"k8s.io/kubernetes/pkg/apis/policy"
|
||||||
"k8s.io/kubernetes/pkg/apis/scheduling"
|
"k8s.io/kubernetes/pkg/apis/scheduling"
|
||||||
"k8s.io/kubernetes/pkg/apis/storage"
|
"k8s.io/kubernetes/pkg/apis/storage"
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
|
utilpointer "k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testData = TestStruct{
|
var testData = TestStruct{
|
||||||
@ -3867,6 +3869,106 @@ func TestPrintRuntimeClass(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintEndpointSlice(t *testing.T) {
|
||||||
|
ipAddressType := discovery.AddressTypeIP
|
||||||
|
tcpProtocol := api.ProtocolTCP
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
endpointSlice discovery.EndpointSlice
|
||||||
|
expect string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
discovery.EndpointSlice{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "abcslice.123",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||||
|
},
|
||||||
|
AddressType: &ipAddressType,
|
||||||
|
Ports: []discovery.EndpointPort{{
|
||||||
|
Name: utilpointer.StringPtr("http"),
|
||||||
|
Port: utilpointer.Int32Ptr(80),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}},
|
||||||
|
Endpoints: []discovery.Endpoint{{
|
||||||
|
Addresses: []string{"10.1.2.3", "2001:db8::1234:5678"},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
"abcslice.123 IP 80 10.1.2.3,2001:db8::1234:5678 0s\n",
|
||||||
|
}, {
|
||||||
|
discovery.EndpointSlice{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "longerslicename.123",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(-3e11)},
|
||||||
|
},
|
||||||
|
AddressType: &ipAddressType,
|
||||||
|
Ports: []discovery.EndpointPort{{
|
||||||
|
Name: utilpointer.StringPtr("http"),
|
||||||
|
Port: utilpointer.Int32Ptr(80),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}, {
|
||||||
|
Name: utilpointer.StringPtr("https"),
|
||||||
|
Port: utilpointer.Int32Ptr(443),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}},
|
||||||
|
Endpoints: []discovery.Endpoint{{
|
||||||
|
Addresses: []string{"10.1.2.3", "2001:db8::1234:5678"},
|
||||||
|
}, {
|
||||||
|
Addresses: []string{"10.2.3.4", "2001:db8::2345:6789"},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
"longerslicename.123 IP 80,443 10.1.2.3,2001:db8::1234:5678,10.2.3.4 + 1 more... 5m\n",
|
||||||
|
}, {
|
||||||
|
discovery.EndpointSlice{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "multiportslice.123",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(-3e11)},
|
||||||
|
},
|
||||||
|
AddressType: &ipAddressType,
|
||||||
|
Ports: []discovery.EndpointPort{{
|
||||||
|
Name: utilpointer.StringPtr("http"),
|
||||||
|
Port: utilpointer.Int32Ptr(80),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}, {
|
||||||
|
Name: utilpointer.StringPtr("https"),
|
||||||
|
Port: utilpointer.Int32Ptr(443),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}, {
|
||||||
|
Name: utilpointer.StringPtr("extra1"),
|
||||||
|
Port: utilpointer.Int32Ptr(3000),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}, {
|
||||||
|
Name: utilpointer.StringPtr("extra2"),
|
||||||
|
Port: utilpointer.Int32Ptr(3001),
|
||||||
|
Protocol: &tcpProtocol,
|
||||||
|
}},
|
||||||
|
Endpoints: []discovery.Endpoint{{
|
||||||
|
Addresses: []string{"10.1.2.3", "2001:db8::1234:5678"},
|
||||||
|
}, {
|
||||||
|
Addresses: []string{"10.2.3.4", "2001:db8::2345:6789"},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
"multiportslice.123 IP 80,443,3000 + 1 more... 10.1.2.3,2001:db8::1234:5678,10.2.3.4 + 1 more... 5m\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
for _, test := range tests {
|
||||||
|
table, err := printers.NewTableGenerator().With(AddHandlers).GenerateTable(&test.endpointSlice, printers.GenerateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
verifyTable(t, table)
|
||||||
|
printer := printers.NewTablePrinter(printers.PrintOptions{NoHeaders: true})
|
||||||
|
if err := printer.PrintObj(table, buf); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if buf.String() != test.expect {
|
||||||
|
t.Errorf("Expected: %s, got: %s", test.expect, buf.String())
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func verifyTable(t *testing.T, table *metav1beta1.Table) {
|
func verifyTable(t *testing.T, table *metav1beta1.Table) {
|
||||||
var panicErr interface{}
|
var panicErr interface{}
|
||||||
func() {
|
func() {
|
||||||
|
@ -14,6 +14,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/networking/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/networking/v1beta1:go_default_library",
|
||||||
@ -63,6 +64,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/discovery/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||||
|
@ -40,6 +40,7 @@ import (
|
|||||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
networkingv1 "k8s.io/api/networking/v1"
|
networkingv1 "k8s.io/api/networking/v1"
|
||||||
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
networkingv1beta1 "k8s.io/api/networking/v1beta1"
|
||||||
@ -169,6 +170,7 @@ func describerMap(clientConfig *rest.Config) (map[schema.GroupKind]describe.Desc
|
|||||||
{Group: corev1.GroupName, Kind: "Endpoints"}: &EndpointsDescriber{c},
|
{Group: corev1.GroupName, Kind: "Endpoints"}: &EndpointsDescriber{c},
|
||||||
{Group: corev1.GroupName, Kind: "ConfigMap"}: &ConfigMapDescriber{c},
|
{Group: corev1.GroupName, Kind: "ConfigMap"}: &ConfigMapDescriber{c},
|
||||||
{Group: corev1.GroupName, Kind: "PriorityClass"}: &PriorityClassDescriber{c},
|
{Group: corev1.GroupName, Kind: "PriorityClass"}: &PriorityClassDescriber{c},
|
||||||
|
{Group: discoveryv1alpha1.GroupName, Kind: "EndpointSlice"}: &EndpointSliceDescriber{c},
|
||||||
{Group: extensionsv1beta1.GroupName, Kind: "ReplicaSet"}: &ReplicaSetDescriber{c},
|
{Group: extensionsv1beta1.GroupName, Kind: "ReplicaSet"}: &ReplicaSetDescriber{c},
|
||||||
{Group: extensionsv1beta1.GroupName, Kind: "NetworkPolicy"}: &NetworkPolicyDescriber{c},
|
{Group: extensionsv1beta1.GroupName, Kind: "NetworkPolicy"}: &NetworkPolicyDescriber{c},
|
||||||
{Group: extensionsv1beta1.GroupName, Kind: "PodSecurityPolicy"}: &PodSecurityPolicyDescriber{c},
|
{Group: extensionsv1beta1.GroupName, Kind: "PodSecurityPolicy"}: &PodSecurityPolicyDescriber{c},
|
||||||
@ -2601,6 +2603,103 @@ func describeEndpoints(ep *corev1.Endpoints, events *corev1.EventList) (string,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EndpointSliceDescriber generates information about an EndpointSlice.
|
||||||
|
type EndpointSliceDescriber struct {
|
||||||
|
clientset.Interface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *EndpointSliceDescriber) Describe(namespace, name string, describerSettings describe.DescriberSettings) (string, error) {
|
||||||
|
c := d.DiscoveryV1alpha1().EndpointSlices(namespace)
|
||||||
|
|
||||||
|
eps, err := c.Get(name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var events *corev1.EventList
|
||||||
|
if describerSettings.ShowEvents {
|
||||||
|
events, _ = d.CoreV1().Events(namespace).Search(scheme.Scheme, eps)
|
||||||
|
}
|
||||||
|
|
||||||
|
return describeEndpointSlice(eps, events)
|
||||||
|
}
|
||||||
|
|
||||||
|
func describeEndpointSlice(eps *discoveryv1alpha1.EndpointSlice, events *corev1.EventList) (string, error) {
|
||||||
|
return tabbedString(func(out io.Writer) error {
|
||||||
|
w := NewPrefixWriter(out)
|
||||||
|
w.Write(LEVEL_0, "Name:\t%s\n", eps.Name)
|
||||||
|
w.Write(LEVEL_0, "Namespace:\t%s\n", eps.Namespace)
|
||||||
|
printLabelsMultiline(w, "Labels", eps.Labels)
|
||||||
|
printAnnotationsMultiline(w, "Annotations", eps.Annotations)
|
||||||
|
|
||||||
|
addressType := "<unset>"
|
||||||
|
if eps.AddressType != nil {
|
||||||
|
addressType = string(*eps.AddressType)
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_0, "AddressType:\t%s\n", addressType)
|
||||||
|
|
||||||
|
if len(eps.Ports) == 0 {
|
||||||
|
w.Write(LEVEL_0, "Ports: <unset>\n")
|
||||||
|
} else {
|
||||||
|
w.Write(LEVEL_0, "Ports:\n")
|
||||||
|
w.Write(LEVEL_1, "Name\tPort\tProtocol\n")
|
||||||
|
w.Write(LEVEL_1, "----\t----\t--------\n")
|
||||||
|
for _, port := range eps.Ports {
|
||||||
|
portName := "<unset>"
|
||||||
|
if port.Name != nil && len(*port.Name) > 0 {
|
||||||
|
portName = *port.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
portNum := "<unset>"
|
||||||
|
if port.Port != nil {
|
||||||
|
portNum = strconv.Itoa(int(*port.Port))
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(LEVEL_1, "%s\t%s\t%s\n", portName, portNum, *port.Protocol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(eps.Endpoints) == 0 {
|
||||||
|
w.Write(LEVEL_0, "Endpoints: <none>\n")
|
||||||
|
} else {
|
||||||
|
w.Write(LEVEL_0, "Endpoints:\n")
|
||||||
|
for i := range eps.Endpoints {
|
||||||
|
endpoint := &eps.Endpoints[i]
|
||||||
|
|
||||||
|
addressesString := strings.Join(endpoint.Addresses, ",")
|
||||||
|
if len(addressesString) == 0 {
|
||||||
|
addressesString = "<none>"
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_1, "- Addresses:\t%s\n", addressesString)
|
||||||
|
|
||||||
|
w.Write(LEVEL_2, "Conditions:\n")
|
||||||
|
readyText := "<unset>"
|
||||||
|
if endpoint.Conditions.Ready != nil {
|
||||||
|
readyText = strconv.FormatBool(*endpoint.Conditions.Ready)
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_3, "Ready:\t%s\n", readyText)
|
||||||
|
|
||||||
|
hostnameText := "<unset>"
|
||||||
|
if endpoint.Hostname != nil {
|
||||||
|
hostnameText = *endpoint.Hostname
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_2, "Hostname:\t%s\n", hostnameText)
|
||||||
|
|
||||||
|
if endpoint.TargetRef != nil {
|
||||||
|
w.Write(LEVEL_2, "TargetRef:\t%s/%s\n", endpoint.TargetRef.Kind, endpoint.TargetRef.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
printLabelsMultilineWithIndent(w, " ", "Topology", "\t", endpoint.Topology, sets.NewString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if events != nil {
|
||||||
|
DescribeEvents(events, w)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ServiceAccountDescriber generates information about a service.
|
// ServiceAccountDescriber generates information about a service.
|
||||||
type ServiceAccountDescriber struct {
|
type ServiceAccountDescriber struct {
|
||||||
clientset.Interface
|
clientset.Interface
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
discoveryv1alpha1 "k8s.io/api/discovery/v1alpha1"
|
||||||
networkingv1 "k8s.io/api/networking/v1"
|
networkingv1 "k8s.io/api/networking/v1"
|
||||||
policyv1beta1 "k8s.io/api/policy/v1beta1"
|
policyv1beta1 "k8s.io/api/policy/v1beta1"
|
||||||
storagev1 "k8s.io/api/storage/v1"
|
storagev1 "k8s.io/api/storage/v1"
|
||||||
@ -2535,6 +2536,14 @@ func TestDescribeEvents(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}, events),
|
}, events),
|
||||||
},
|
},
|
||||||
|
"EndpointSliceDescriber": &EndpointSliceDescriber{
|
||||||
|
fake.NewSimpleClientset(&discoveryv1alpha1.EndpointSlice{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
}, events),
|
||||||
|
},
|
||||||
// TODO(jchaloup): add tests for:
|
// TODO(jchaloup): add tests for:
|
||||||
// - IngressDescriber
|
// - IngressDescriber
|
||||||
// - JobDescriber
|
// - JobDescriber
|
||||||
@ -3193,6 +3202,83 @@ func TestDescribeStatefulSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDescribeEndpointSlice(t *testing.T) {
|
||||||
|
addressTypeIP := discoveryv1alpha1.AddressTypeIP
|
||||||
|
protocolTCP := corev1.ProtocolTCP
|
||||||
|
port80 := int32(80)
|
||||||
|
|
||||||
|
fake := fake.NewSimpleClientset(&discoveryv1alpha1.EndpointSlice{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "foo.123",
|
||||||
|
Namespace: "bar",
|
||||||
|
},
|
||||||
|
AddressType: &addressTypeIP,
|
||||||
|
Endpoints: []discoveryv1alpha1.Endpoint{
|
||||||
|
{
|
||||||
|
Addresses: []string{"1.2.3.4", "1.2.3.5"},
|
||||||
|
Conditions: discoveryv1alpha1.EndpointConditions{Ready: utilpointer.BoolPtr(true)},
|
||||||
|
TargetRef: &corev1.ObjectReference{Kind: "Pod", Name: "test-123"},
|
||||||
|
Topology: map[string]string{
|
||||||
|
"topology.kubernetes.io/zone": "us-central1-a",
|
||||||
|
"topology.kubernetes.io/region": "us-central1",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
Addresses: []string{"1.2.3.6", "1.2.3.7"},
|
||||||
|
Conditions: discoveryv1alpha1.EndpointConditions{Ready: utilpointer.BoolPtr(true)},
|
||||||
|
TargetRef: &corev1.ObjectReference{Kind: "Pod", Name: "test-124"},
|
||||||
|
Topology: map[string]string{
|
||||||
|
"topology.kubernetes.io/zone": "us-central1-b",
|
||||||
|
"topology.kubernetes.io/region": "us-central1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Ports: []discoveryv1alpha1.EndpointPort{
|
||||||
|
{
|
||||||
|
Protocol: &protocolTCP,
|
||||||
|
Port: &port80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
||||||
|
d := EndpointSliceDescriber{c}
|
||||||
|
out, err := d.Describe("bar", "foo.123", describe.DescriberSettings{ShowEvents: true})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOut := `Name: foo.123
|
||||||
|
Namespace: bar
|
||||||
|
Labels: <none>
|
||||||
|
Annotations: <none>
|
||||||
|
AddressType: IP
|
||||||
|
Ports:
|
||||||
|
Name Port Protocol
|
||||||
|
---- ---- --------
|
||||||
|
<unset> 80 TCP
|
||||||
|
Endpoints:
|
||||||
|
- Addresses: 1.2.3.4,1.2.3.5
|
||||||
|
Conditions:
|
||||||
|
Ready: true
|
||||||
|
Hostname: <unset>
|
||||||
|
TargetRef: Pod/test-123
|
||||||
|
Topology: topology.kubernetes.io/region=us-central1
|
||||||
|
topology.kubernetes.io/zone=us-central1-a
|
||||||
|
- Addresses: 1.2.3.6,1.2.3.7
|
||||||
|
Conditions:
|
||||||
|
Ready: true
|
||||||
|
Hostname: <unset>
|
||||||
|
TargetRef: Pod/test-124
|
||||||
|
Topology: topology.kubernetes.io/region=us-central1
|
||||||
|
topology.kubernetes.io/zone=us-central1-b
|
||||||
|
Events: <none>` + "\n"
|
||||||
|
|
||||||
|
if out != expectedOut {
|
||||||
|
t.Logf(out)
|
||||||
|
t.Errorf("expected : %q\n but got output:\n %q", expectedOut, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// boolPtr returns a pointer to a bool
|
// boolPtr returns a pointer to a bool
|
||||||
func boolPtr(b bool) *bool {
|
func boolPtr(b bool) *bool {
|
||||||
o := b
|
o := b
|
||||||
|
Loading…
Reference in New Issue
Block a user