Skip to content

Commit

Permalink
feat: kubectl neat supports objects
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe authored and moshloop committed Jan 12, 2024
1 parent 4b53c3d commit ac2c873
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 14 deletions.
7 changes: 6 additions & 1 deletion conv/conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package conv

import (
"encoding/json"
"fmt"
"math"
"reflect"
Expand Down Expand Up @@ -137,7 +138,11 @@ func ToString(in interface{}) string {
if s, ok := in.([]byte); ok {
return string(s)
}

if reflect.TypeOf(in).Kind() == reflect.Map {
if s, err := json.Marshal(in); err == nil {
return string(s)
}
}
v, ok := printableValue(reflect.ValueOf(in))
if ok {
in = v
Expand Down
4 changes: 2 additions & 2 deletions kubernetes/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func Neat(in, outputFormat string) (string, error) {
func k8sNeat() cel.EnvOption {
return cel.Function("k8s.neat",
cel.Overload("k8s_neat",
[]*cel.Type{cel.StringType},
[]*cel.Type{cel.DynType},
cel.StringType,
cel.UnaryBinding(func(obj ref.Val) ref.Val {
objVal := conv.ToString(obj.Value())
Expand All @@ -34,7 +34,7 @@ func k8sNeat() cel.EnvOption {
func k8sNeatWithOption() cel.EnvOption {
return cel.Function("k8s.neat",
cel.Overload("k8s_neat_with_option",
[]*cel.Type{cel.StringType, cel.StringType},
[]*cel.Type{cel.DynType, cel.StringType},
cel.StringType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
objVal := conv.ToString(args[0].Value())
Expand Down
36 changes: 25 additions & 11 deletions tests/cel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/flanksource/gomplate/v3"
"github.com/flanksource/gomplate/v3/kubernetes"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

func panIf(err error) {
Expand All @@ -17,10 +18,15 @@ func panIf(err error) {
}
}

func executeTemplate(t *testing.T, i int, input string, expectedOutput any, environment map[string]any) {
func executeTemplate(t *testing.T, i int, input string, expectedOutput any, environment map[string]any, jsonCompare bool) {
out, err := gomplate.RunExpression(environment, gomplate.Template{Expression: input})
panIf(err)
assert.EqualValues(t, expectedOutput, out, fmt.Sprintf("Test:%d failed", i+1))

if jsonCompare {
assert.JSONEq(t, expectedOutput.(string), out.(string), fmt.Sprintf("Test:%d failed", i+1))
} else {
assert.EqualValues(t, expectedOutput, out, fmt.Sprintf("Test:%d failed", i+1))
}
}

type Test struct {
Expand Down Expand Up @@ -410,7 +416,7 @@ func TestCelVariadic(t *testing.T) {
}

for i, td := range testData {
executeTemplate(t, i, td.Input, td.Output, nil)
executeTemplate(t, i, td.Input, td.Output, nil, false)
}
}

Expand All @@ -423,7 +429,7 @@ func TestCelSliceReturn(t *testing.T) {
}

for i, td := range testData {
executeTemplate(t, i, td.Input, td.Output, nil)
executeTemplate(t, i, td.Input, td.Output, nil, false)
}
}

Expand All @@ -437,8 +443,9 @@ func TestCelK8sResources(t *testing.T) {

func TestCelK8s(t *testing.T) {
testData := []struct {
Input string
Output any
Input string
Output any
jsonCompare bool
}{
{Input: `k8s.isHealthy(healthy_obj)`, Output: true},
{Input: `k8s.isHealthy(unhealthy_obj)`, Output: false},
Expand All @@ -450,23 +457,30 @@ func TestCelK8s(t *testing.T) {
{Input: `dyn(obj_list).all(i, k8s.isHealthy(i))`, Output: false},
{Input: `dyn(unstructured_list).all(i, k8s.isHealthy(i))`, Output: false},
{Input: `k8s.isHealthy(unhealthy_obj)`, Output: false},
{Input: `k8s.neat(service_raw)`, Output: kubernetes.TestServiceNeat},
{Input: `k8s.neat(pod_raw)`, Output: kubernetes.TestPodNeat},
{Input: `k8s.neat(service_raw)`, Output: kubernetes.TestServiceNeat, jsonCompare: true},
{Input: `k8s.neat(pod_raw)`, Output: kubernetes.TestPodNeat, jsonCompare: true},
{Input: `k8s.neat(pod_raw_obj.Object)`, Output: kubernetes.TestPodNeat, jsonCompare: true},
{Input: `k8s.neat(pv_raw, 'yaml')`, Output: kubernetes.TestPVYAMLRaw},
}

var podRaw unstructured.Unstructured
if err := json.Unmarshal([]byte(kubernetes.TestPodRaw), &podRaw.Object); err != nil {
t.Fatal(err)
}

environment := map[string]any{
"healthy_obj": kubernetes.TestHealthy,
"unhealthy_obj": kubernetes.TestUnhealthy,
"obj_list": []string{kubernetes.TestHealthy, kubernetes.TestUnhealthy},
"unstructured_list": kubernetes.TestUnstructuredList,
"service_raw": kubernetes.TestServiceRaw,
"pod_raw": kubernetes.TestPodRaw,
"pod_raw_obj": podRaw,
"pv_raw": kubernetes.TestPVJsonRaw,
}

for i, td := range testData {
executeTemplate(t, i, td.Input, td.Output, environment)
executeTemplate(t, i, td.Input, td.Output, environment, td.jsonCompare)
}
}

Expand All @@ -486,7 +500,7 @@ func TestCelK8sCPUResourceUnits(t *testing.T) {
}

for i, td := range testData {
executeTemplate(t, i, td.Input, td.Output, nil)
executeTemplate(t, i, td.Input, td.Output, nil, false)
}
}

Expand Down Expand Up @@ -516,7 +530,7 @@ func TestCelK8sMemoryResourceUnits(t *testing.T) {
}

for i, td := range testData {
executeTemplate(t, i, td.Input, td.Output, nil)
executeTemplate(t, i, td.Input, td.Output, nil, false)
}
}

Expand Down

0 comments on commit ac2c873

Please sign in to comment.