Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support -o json and -o name on get #60

Merged
merged 9 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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())
}
sderosiaux marked this conversation as resolved.
Show resolved Hide resolved
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 "$@"
Loading