Skip to content

Commit

Permalink
Add describer and printer for ClusterCIDR API
Browse files Browse the repository at this point in the history
  • Loading branch information
sarveshr7 committed Aug 2, 2022
1 parent 529b04e commit 76041b7
Show file tree
Hide file tree
Showing 4 changed files with 457 additions and 1 deletion.
64 changes: 64 additions & 0 deletions pkg/printers/internalversion/printers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
flowcontrolv1beta2 "k8s.io/api/flowcontrol/v1beta2"
networkingv1alpha1 "k8s.io/api/networking/v1alpha1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
schedulingv1 "k8s.io/api/scheduling/v1"
Expand Down Expand Up @@ -591,6 +592,18 @@ func AddHandlers(h printers.PrintHandler) {
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
}
h.TableHandler(scaleColumnDefinitions, printScale)

clusterCIDRColumnDefinitions := []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "PerNodeHostBits", Type: "string", Description: networkingv1alpha1.ClusterCIDRSpec{}.SwaggerDoc()["perNodeHostBits"]},
{Name: "IPv4", Type: "string", Description: networkingv1alpha1.ClusterCIDRSpec{}.SwaggerDoc()["ipv4"]},
{Name: "IPv6", Type: "string", Description: networkingv1alpha1.ClusterCIDRSpec{}.SwaggerDoc()["ipv6"]},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
{Name: "NodeSelector", Type: "string", Priority: 1, Description: networkingv1alpha1.ClusterCIDRSpec{}.SwaggerDoc()["nodeSelector"]},
}

h.TableHandler(clusterCIDRColumnDefinitions, printClusterCIDR)
h.TableHandler(clusterCIDRColumnDefinitions, printClusterCIDRList)
}

// Pass ports=nil for all ports.
Expand Down Expand Up @@ -2624,6 +2637,57 @@ func printPriorityLevelConfigurationList(list *flowcontrol.PriorityLevelConfigur
return rows, nil
}

func printClusterCIDR(obj *networking.ClusterCIDR, options printers.GenerateOptions) ([]metav1.TableRow, error) {
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
ipv4 := "<none>"
ipv6 := "<none>"

if obj.Spec.IPv4 != "" {
ipv4 = obj.Spec.IPv4
}
if obj.Spec.IPv6 != "" {
ipv6 = obj.Spec.IPv6
}

row.Cells = append(row.Cells, obj.Name, fmt.Sprint(obj.Spec.PerNodeHostBits), ipv4, ipv6, translateTimestampSince(obj.CreationTimestamp))
if options.Wide {
nodeSelector := "<none>"
if obj.Spec.NodeSelector != nil {
allTerms := make([]string, 0)
for _, term := range obj.Spec.NodeSelector.NodeSelectorTerms {
if len(term.MatchExpressions) > 0 {
matchExpressions := fmt.Sprintf("MatchExpressions: %v", term.MatchExpressions)
allTerms = append(allTerms, matchExpressions)
}

if len(term.MatchFields) > 0 {
matchFields := fmt.Sprintf("MatchFields: %v", term.MatchFields)
allTerms = append(allTerms, matchFields)
}
}
nodeSelector = strings.Join(allTerms, ",")
}

row.Cells = append(row.Cells, nodeSelector)
}

return []metav1.TableRow{row}, nil
}

func printClusterCIDRList(list *networking.ClusterCIDRList, options printers.GenerateOptions) ([]metav1.TableRow, error) {
rows := make([]metav1.TableRow, 0, len(list.Items))
for i := range list.Items {
r, err := printClusterCIDR(&list.Items[i], options)
if err != nil {
return nil, err
}
rows = append(rows, r...)
}
return rows, nil
}

func printScale(obj *autoscaling.Scale, options printers.GenerateOptions) ([]metav1.TableRow, error) {
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
Expand Down
274 changes: 274 additions & 0 deletions pkg/printers/internalversion/printers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6184,3 +6184,277 @@ func TestTableRowDeepCopyShouldNotPanic(t *testing.T) {
})
}
}

func TestPrintClusterCIDR(t *testing.T) {
ipv4CIDR := "10.1.0.0/16"
perNodeHostBits := int32(8)
ipv6CIDR := "fd00:1:1::/64"

tests := []struct {
ccc networking.ClusterCIDR
options printers.GenerateOptions
expected []metav1.TableRow
}{
{
// Test name, IPv4 only with no node selector.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test1"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
},
},
options: printers.GenerateOptions{},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age.
expected: []metav1.TableRow{{Cells: []interface{}{"test1", "8", ipv4CIDR, "<none>", "<unknown>"}}},
},
{
// Test name, IPv4 only with node selector, Not wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test2"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
// Does NOT get printed.
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
options: printers.GenerateOptions{},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age.
expected: []metav1.TableRow{{Cells: []interface{}{"test2", "8", ipv4CIDR, "<none>", "<unknown>"}}},
},
{
// Test name, IPv4 only with no node selector, wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test3"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector .
expected: []metav1.TableRow{{Cells: []interface{}{"test3", "8", ipv4CIDR, "<none>", "<unknown>", "<none>"}}},
},
{
// Test name, IPv4 only with node selector, wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test4"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector .
expected: []metav1.TableRow{{Cells: []interface{}{"test4", "8", ipv4CIDR, "<none>", "<unknown>", "MatchExpressions: [{foo In [bar]}]"}}},
},
{
// Test name, IPv6 only with no node selector.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test5"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv6: ipv6CIDR,
},
},
options: printers.GenerateOptions{},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age
expected: []metav1.TableRow{{Cells: []interface{}{"test5", "8", "<none>", ipv6CIDR, "<unknown>"}}},
},
{
// Test name, IPv6 only with node selector, Not wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test6"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv6: ipv6CIDR,
// Does NOT get printed.
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
options: printers.GenerateOptions{},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age.
expected: []metav1.TableRow{{Cells: []interface{}{"test6", "8", "<none>", ipv6CIDR, "<unknown>"}}},
},
{
// Test name, IPv6 only with no node selector, wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test7"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv6: ipv6CIDR,
},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector .
expected: []metav1.TableRow{{Cells: []interface{}{"test7", "8", "<none>", ipv6CIDR, "<unknown>", "<none>"}}},
},
{
// Test name, IPv6 only with node selector, wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test8"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv6: ipv6CIDR,
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector .
expected: []metav1.TableRow{{Cells: []interface{}{"test8", "8", "<none>", ipv6CIDR, "<unknown>", "MatchExpressions: [{foo In [bar]}]"}}},
},
{
// Test name, DualStack with no node selector.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test9"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
IPv6: ipv6CIDR,
},
},
options: printers.GenerateOptions{},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age.
expected: []metav1.TableRow{{Cells: []interface{}{"test9", "8", ipv4CIDR, ipv6CIDR, "<unknown>"}}},
},
{
// Test name,DualStack with node selector, Not wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test10"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
IPv6: ipv6CIDR,
// Does NOT get printed.
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
options: printers.GenerateOptions{},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age.
expected: []metav1.TableRow{{Cells: []interface{}{"test10", "8", ipv4CIDR, ipv6CIDR, "<unknown>"}}},
},
{
// Test name, DualStack with no node selector, wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test11"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
IPv6: ipv6CIDR,
},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector.
expected: []metav1.TableRow{{Cells: []interface{}{"test11", "8", ipv4CIDR, ipv6CIDR, "<unknown>", "<none>"}}},
},
{
// Test name, DualStack with node selector, wide.
ccc: networking.ClusterCIDR{
ObjectMeta: metav1.ObjectMeta{Name: "test12"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: perNodeHostBits,
IPv4: ipv4CIDR,
IPv6: ipv6CIDR,
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
options: printers.GenerateOptions{Wide: true},
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector .
expected: []metav1.TableRow{{Cells: []interface{}{"test12", "8", ipv4CIDR, ipv6CIDR, "<unknown>", "MatchExpressions: [{foo In [bar]}]"}}},
},
}

for i, test := range tests {
rows, err := printClusterCIDR(&test.ccc, test.options)
if err != nil {
t.Fatal(err)
}
for i := range rows {
rows[i].Object.Object = nil
}
if !reflect.DeepEqual(test.expected, rows) {
t.Errorf("%d mismatch: %s", i, diff.ObjectReflectDiff(test.expected, rows))
}
}
}

func makeNodeSelector(key string, op api.NodeSelectorOperator, values []string) *api.NodeSelector {
return &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{
{
MatchExpressions: []api.NodeSelectorRequirement{
{
Key: key,
Operator: op,
Values: values,
},
},
},
},
}
}

func TestPrintClusterCIDRList(t *testing.T) {

cccList := networking.ClusterCIDRList{
Items: []networking.ClusterCIDR{
{
ObjectMeta: metav1.ObjectMeta{Name: "ccc1"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: int32(8),
IPv4: "10.1.0.0/16",
IPv6: "fd00:1:1::/64",
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "ccc2"},
Spec: networking.ClusterCIDRSpec{
PerNodeHostBits: int32(8),
IPv4: "10.2.0.0/16",
IPv6: "fd00:2:1::/64",
NodeSelector: makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"}),
},
},
},
}

tests := []struct {
options printers.GenerateOptions
expected []metav1.TableRow
}{
{
// Test name, DualStack with node selector, wide.
options: printers.GenerateOptions{Wide: false},
expected: []metav1.TableRow{
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age.
{Cells: []interface{}{"ccc1", "8", "10.1.0.0/16", "fd00:1:1::/64", "<unknown>"}},
{Cells: []interface{}{"ccc2", "8", "10.2.0.0/16", "fd00:2:1::/64", "<unknown>"}},
},
},
{
// Test name, DualStack with node selector, wide.
options: printers.GenerateOptions{Wide: true},
expected: []metav1.TableRow{
// Columns: Name, PerNodeHostBits, IPv4, IPv6, Age, NodeSelector.
{Cells: []interface{}{"ccc1", "8", "10.1.0.0/16", "fd00:1:1::/64", "<unknown>", "MatchExpressions: [{foo In [bar]}]"}},
{Cells: []interface{}{"ccc2", "8", "10.2.0.0/16", "fd00:2:1::/64", "<unknown>", "MatchExpressions: [{foo In [bar]}]"}},
},
},
}

for _, test := range tests {
rows, err := printClusterCIDRList(&cccList, test.options)
if err != nil {
t.Fatalf("Error printing service list: %#v", err)
}
for i := range rows {
rows[i].Object.Object = nil
}
if !reflect.DeepEqual(test.expected, rows) {
t.Errorf("mismatch: %s", diff.ObjectReflectDiff(test.expected, rows))
}
}
}

0 comments on commit 76041b7

Please sign in to comment.