Skip to content

Commit

Permalink
Support -o json and -o name on get (#60)
Browse files Browse the repository at this point in the history
* Support -o json

* Cleanup

* Err

* Fix

* Add -o name

* Review: use enum

* Fix

* Add tests

* Fix tests
  • Loading branch information
sderosiaux authored Aug 28, 2024
1 parent 4ca82e8 commit 9911cbe
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 32 deletions.
74 changes: 70 additions & 4 deletions cmd/get.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"encoding/json"
"fmt"
"os"
"strconv"
Expand All @@ -10,8 +11,27 @@ import (
"github.com/conduktor/ctl/schema"
"github.com/conduktor/ctl/utils"
"github.com/spf13/cobra"
"github.com/thediveo/enumflag/v2"
)

type OutputFormat enumflag.Flag

const (
JSON OutputFormat = iota
YAML
NAME
)

var OutputFormatIds = map[OutputFormat][]string{
JSON: {"json"},
YAML: {"yaml"},
NAME: {"name"},
}

func (o OutputFormat) String() string {
return OutputFormatIds[o][0]
}

var getCmd = &cobra.Command{
Use: "get",
Short: "Get resource of a given kind",
Expand Down Expand Up @@ -52,8 +72,47 @@ func buildAlias(name string) []string {
return []string{strings.ToLower(name), removeTrailingSIfAny(strings.ToLower(name)), removeTrailingSIfAny(name)}
}

func printResource(result interface{}, format OutputFormat) error {
switch format {
case JSON:
jsonOutput, err := json.MarshalIndent(result, "", " ")
if err != nil {
return fmt.Errorf("error marshalling JSON: %s\n%s", err, result)
}
fmt.Println(string(jsonOutput))
case NAME:
// show Kind/Name
switch res := result.(type) {
case []resource.Resource:
for _, r := range res {
fmt.Println(r.Kind + "/" + r.Name)
}
case resource.Resource:
fmt.Println(res.Kind + "/" + res.Name)
default:
return fmt.Errorf("unexpected resource type")
}
case YAML:
switch res := result.(type) {
case []resource.Resource:
for _, r := range res {
fmt.Println("---") // '---' indicates the start of a new document in YAML
r.PrintPreservingOriginalFieldOrder()
}
case resource.Resource:
res.PrintPreservingOriginalFieldOrder()
default:
return fmt.Errorf("unexpected resource type")
}
default:
return fmt.Errorf("invalid output format %s", format.String())
}
return nil
}

func initGet(kinds schema.KindCatalog) {
rootCmd.AddCommand(getCmd)
var format OutputFormat = YAML

for name, kind := range kinds {
gatewayKind, isGatewayKind := kind.GetLatestKindVersion().(*schema.GatewayKindVersion)
Expand All @@ -80,25 +139,31 @@ func initGet(kinds schema.KindCatalog) {
parentValue[i] = *v
}
var err error

if len(args) == 0 {
var result []resource.Resource
if isGatewayKind {
result, err = gatewayApiClient().Get(&kind, parentValue, queryParams)
} else {
result, err = consoleApiClient().Get(&kind, parentValue, queryParams)
}
for _, r := range result {
r.PrintPreservingOriginalFieldOrder()
fmt.Println("---")
if err != nil {
fmt.Fprintf(os.Stderr, "Error fetching resources: %s\n", err)
return
}
err = printResource(result, format)
} else if len(args) == 1 {
var result resource.Resource
if isGatewayKind {
result, err = gatewayApiClient().Describe(&kind, parentValue, args[0])
} else {
result, err = consoleApiClient().Describe(&kind, parentValue, args[0])
}
result.PrintPreservingOriginalFieldOrder()
if err != nil {
fmt.Fprintf(os.Stderr, "Error describing resource: %s\n", err)
return
}
err = printResource(result, format)
}
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
Expand Down Expand Up @@ -127,6 +192,7 @@ func initGet(kinds schema.KindCatalog) {
kindCmd.MarkFlagRequired(flag.FlagName)
}
}
kindCmd.Flags().VarP(enumflag.New(&format, "output", OutputFormatIds, enumflag.EnumCaseInsensitive), "output", "o", "Output format. One of: json|yaml|name (default is yaml)")
getCmd.AddCommand(kindCmd)
}
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/conduktor/ctl
go 1.22.0

require (
github.com/Jeffail/gabs/v2 v2.7.0
github.com/davecgh/go-spew v1.1.1
github.com/ghodss/yaml v1.0.0
github.com/go-resty/resty/v2 v2.11.0
Expand All @@ -11,7 +12,6 @@ require (
github.com/spf13/cobra v1.8.0
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a
gopkg.in/yaml.v3 v3.0.1
github.com/Jeffail/gabs/v2 v2.7.0
)

require (
Expand All @@ -21,6 +21,7 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/thediveo/enumflag/v2 v2.0.5 // indirect
github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
golang.org/x/net v0.23.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.28.1 h1:MijcGUbfYuznzK/5R4CPNoUP/9Xvuo20sXfEm6XxoTA=
github.com/pb33f/libopenapi v0.15.14 h1:A0fn45jbthDyFGXfu5bYIZVsWyPI6hJYm3wG143MT8o=
github.com/pb33f/libopenapi v0.15.14/go.mod h1:PEXNwvtT4KNdjrwudp5OYnD1ryqK6uJ68aMNyWvoMuc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -83,6 +84,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/thediveo/enumflag/v2 v2.0.5 h1:VJjvlAqUb6m6mxOrB/0tfBJI0Kvi9wJ8ulh38xK87i8=
github.com/thediveo/enumflag/v2 v2.0.5/go.mod h1:0NcG67nYgwwFsAvoQCmezG0J0KaIxZ0f7skg9eLq1DA=
github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk=
github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
Expand Down
60 changes: 33 additions & 27 deletions test_final_exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,46 @@ function cleanup {
docker compose -f "$SCRIPTDIR/docker/docker-compose.yml" down
}

run() {
docker compose -f docker/docker-compose.yml run --rm "$@"
}

trap cleanup EXIT
main() {
cd "$SCRIPTDIR"
docker compose -f docker/docker-compose.yml build
docker compose -f docker/docker-compose.yml up -d mock mockGateway
sleep 1
docker compose -f docker/docker-compose.yml run --rm conduktor apply -f /test_resource.yml
docker compose -f docker/docker-compose.yml run --rm conduktor apply -f /
docker compose -f docker/docker-compose.yml run --rm conduktor delete -f /test_resource.yml
docker compose -f docker/docker-compose.yml run --rm conduktor apply -f /
docker compose -f docker/docker-compose.yml run --rm conduktor get Topic yolo --cluster=my-cluster
docker compose -f docker/docker-compose.yml run --rm conduktor delete Topic yolo -v --cluster=my-cluster
docker compose -f docker/docker-compose.yml run --rm -e CDK_USER=admin -e CDK_PASSWORD=secret conduktor login
docker compose -f docker/docker-compose.yml run --rm -e CDK_USER=admin -e CDK_PASSWORD=secret -e CDK_API_KEY="" conduktor get KafkaCluster my_kafka_cluster
docker compose -f docker/docker-compose.yml run --rm conduktor token list admin
docker compose -f docker/docker-compose.yml run --rm conduktor token list application-instance -i=my_app_instance
docker compose -f docker/docker-compose.yml run --rm conduktor token create admin a_admin_token
docker compose -f docker/docker-compose.yml run --rm conduktor token create application-instance -i=my_app_instance a_admin_token
docker compose -f docker/docker-compose.yml run --rm conduktor token delete 0-0-0-0-0
sleep 2
run conduktor apply -f /test_resource.yml
run conduktor apply -f /
run conduktor delete -f /test_resource.yml
run conduktor apply -f /
run conduktor get Topic yolo --cluster=my-cluster
run conduktor get Topic yolo --cluster=my-cluster -o yaml
run conduktor get Topic yolo --cluster=my-cluster -o name
run conduktor delete Topic yolo -v --cluster=my-cluster
run -e CDK_USER=admin -e CDK_PASSWORD=secret conduktor login
run -e CDK_USER=admin -e CDK_PASSWORD=secret -e CDK_API_KEY="" conduktor get KafkaCluster my_kafka_cluster
run conduktor token list admin
run conduktor token list application-instance -i=my_app_instance
run conduktor token create admin a_admin_token
run conduktor token create application-instance -i=my_app_instance a_admin_token
run conduktor token delete 0-0-0-0-0

# Gateway
docker compose -f docker/docker-compose.yml run --rm conduktor apply -f /test_resource_gw.yml
docker compose -f docker/docker-compose.yml run --rm conduktor delete VirtualCluster vcluster1
docker compose -f docker/docker-compose.yml run --rm conduktor get VirtualCluster
docker compose -f docker/docker-compose.yml run --rm conduktor get VirtualCluster vcluster1
docker compose -f docker/docker-compose.yml run --rm conduktor get GatewayGroup
docker compose -f docker/docker-compose.yml run --rm conduktor get GatewayGroup g1
docker compose -f docker/docker-compose.yml run --rm conduktor get AliasTopic --show-defaults --name=yo --vcluster=mycluster1
docker compose -f docker/docker-compose.yml run --rm conduktor get ConcentrationRule --show-defaults --name=yo --vcluster=mycluster1
docker compose -f docker/docker-compose.yml run --rm conduktor get GatewayServiceAccount --show-defaults --name=yo --vcluster=mycluster1
docker compose -f docker/docker-compose.yml run --rm conduktor get interceptor --group=g1 --name=yo --username=me --vcluster=mycluster1
docker compose -f docker/docker-compose.yml run --rm conduktor delete aliastopic aliastopicname --vcluster=v1
docker compose -f docker/docker-compose.yml run --rm conduktor delete concentrationrule cr1 --vcluster=v1
docker compose -f docker/docker-compose.yml run --rm conduktor delete gatewayserviceaccount s1 --vcluster=v1
run conduktor apply -f /test_resource_gw.yml
run conduktor delete VirtualCluster vcluster1
run conduktor get VirtualCluster
run conduktor get VirtualCluster vcluster1
run conduktor get GatewayGroup
run conduktor get GatewayGroup g1
run conduktor get AliasTopic --show-defaults --name=yo --vcluster=mycluster1
run conduktor get ConcentrationRule --show-defaults --name=yo --vcluster=mycluster1
run conduktor get GatewayServiceAccount --show-defaults --name=yo --vcluster=mycluster1
run conduktor get interceptor --group=g1 --name=yo --username=me --vcluster=mycluster1
run conduktor delete aliastopic aliastopicname --vcluster=v1
run conduktor delete concentrationrule cr1 --vcluster=v1
run conduktor delete gatewayserviceaccount s1 --vcluster=v1
}

main "$@"

0 comments on commit 9911cbe

Please sign in to comment.