Skip to content

Commit

Permalink
Implemented json output.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielRailean committed Jan 17, 2023
1 parent 0f2f31f commit e6264b7
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 15 deletions.
61 changes: 55 additions & 6 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
Expand Down Expand Up @@ -40,6 +41,25 @@ const (
modeKongEnterprise
)

type summary struct
{
Creating int32
Updating int32
Deleting int32
Total int32
}

type jsonOutput struct
{
Changes diff.EntityChanges
Summary summary
Warnings []string
Errors []string
}

var jsonOut jsonOutput
var isJsonOut bool

func getMode(targetContent *file.Content) mode {
if inKonnectMode(targetContent) {
return modeKonnect
Expand Down Expand Up @@ -74,17 +94,27 @@ func workspaceExists(ctx context.Context, config utils.KongClientConfig, workspa

func getWorkspaceName(workspaceFlag string, targetContent *file.Content) string {
if workspaceFlag != targetContent.Workspace && workspaceFlag != "" {
cprint.DeletePrintf("Warning: Workspace '%v' specified via --workspace flag is "+
"different from workspace '%v' found in state file(s).\n", workspaceFlag, targetContent.Workspace)
warning := fmt.Sprintf("Warning: Workspace '%v' specified via --workspace flag is "+
"different from workspace '%v' found in state file(s).", workspaceFlag, targetContent.Workspace)
if(isJsonOut){
jsonOut.Warnings = append(jsonOut.Warnings, warning)
}else{
cprint.DeletePrintf(warning+"\n")
}
return workspaceFlag
}
return targetContent.Workspace
}

func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,
delay int, workspace string,
delay int, workspace string, isJsonOutput bool,
) error {
// read target file
if(isJsonOutput){
isJsonOut = true
jsonOut.Errors = []string{}
jsonOut.Warnings = []string{}
}
targetContent, err := file.GetContentFromFiles(filenames)
if err != nil {
return err
Expand Down Expand Up @@ -228,12 +258,21 @@ func syncMain(ctx context.Context, filenames []string, dry bool, parallelism,

totalOps, err := performDiff(ctx, currentState, targetState, dry, parallelism, delay, kongClient)
if err != nil {
if(isJsonOut){
jsonOut.Errors = append(jsonOut.Errors, err.Error())
}
return err
}

if diffCmdNonZeroExitCode && totalOps > 0 {
os.Exit(exitCodeDiffDetection)
}
if(isJsonOutput){
jsonOutStr, jsonErr := json.MarshalIndent(jsonOut, "", " ")
if jsonErr != nil {
return jsonErr
}
cprint.CreatePrintf(string(jsonOutStr)+"\n")
}
return nil
}

Expand Down Expand Up @@ -287,13 +326,23 @@ func performDiff(ctx context.Context, currentState, targetState *state.KongState
return 0, err
}

stats, errs := s.Solve(ctx, parallelism, dry)
stats, errs, changes := s.Solve(ctx, parallelism, dry, isJsonOut)
// print stats before error to report completed operations
printStats(stats)
if(!isJsonOut){
printStats(stats)
}
if errs != nil {
return 0, utils.ErrArray{Errors: errs}
}
totalOps := stats.CreateOps.Count() + stats.UpdateOps.Count() + stats.DeleteOps.Count()

jsonOut.Changes = changes
jsonOut.Summary = summary{
Creating: stats.CreateOps.Count(),
Updating: stats.UpdateOps.Count(),
Deleting: stats.DeleteOps.Count(),
Total: totalOps,
}
return int(totalOps), nil
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/common_konnect.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func syncKonnect(ctx context.Context,
return err
}

stats, errs := s.Solve(ctx, parallelism, dry)
stats, errs, _ := s.Solve(ctx, parallelism, dry, false)
// print stats before error to report completed operations
printStats(stats)
if errs != nil {
Expand Down
5 changes: 4 additions & 1 deletion cmd/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var (
diffCmdParallelism int
diffCmdNonZeroExitCode bool
diffWorkspace string
diffJsonOutput bool
)

// newDiffCmd represents the diff command
Expand All @@ -27,7 +28,7 @@ that will be created, updated, or deleted.
Args: validateNoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return syncMain(cmd.Context(), diffCmdKongStateFile, true,
diffCmdParallelism, 0, diffWorkspace)
diffCmdParallelism, 0, diffWorkspace, diffJsonOutput)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(diffCmdKongStateFile) == 0 {
Expand Down Expand Up @@ -65,6 +66,8 @@ that will be created, updated, or deleted.
"and exit code 1 if an error occurs.")
diffCmd.Flags().BoolVar(&dumpConfig.SkipCACerts, "skip-ca-certificates",
false, "do not diff CA certificates.")
diffCmd.Flags().BoolVar(&diffJsonOutput, "enable-json-output",
false, "provide JSON output to std out")
addSilenceEventsFlag(diffCmd.Flags())
return diffCmd
}
5 changes: 4 additions & 1 deletion cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var (
syncCmdParallelism int
syncCmdDBUpdateDelay int
syncWorkspace string
syncJsonOutput bool
)

// newSyncCmd represents the sync command
Expand All @@ -24,7 +25,7 @@ to get Kong's state in sync with the input state.`,
Args: validateNoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return syncMain(cmd.Context(), syncCmdKongStateFile, false,
syncCmdParallelism, syncCmdDBUpdateDelay, syncWorkspace)
syncCmdParallelism, syncCmdDBUpdateDelay, syncWorkspace, syncJsonOutput)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(syncCmdKongStateFile) == 0 {
Expand Down Expand Up @@ -62,6 +63,8 @@ to get Kong's state in sync with the input state.`,
"See `db_update_propagation` in kong.conf.")
syncCmd.Flags().BoolVar(&dumpConfig.SkipCACerts, "skip-ca-certificates",
false, "do not sync CA certificates.")
syncCmd.Flags().BoolVar(&syncJsonOutput, "enable-json-output",
false, "provide JSON output to std out")
addSilenceEventsFlag(syncCmd.Flags())
return syncCmd
}
50 changes: 44 additions & 6 deletions diff/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ import (
"github.com/kong/go-kong/kong"
)

type entityState struct
{
Name string
OldState any
NewState any
}

type EntityChanges struct
{
Creating []entityState
Updating []entityState
Deleting []entityState
}

var errEnqueueFailed = errors.New("failed to queue event")

func defaultBackOff() backoff.BackOff {
Expand Down Expand Up @@ -377,7 +391,7 @@ func generateDiffString(e crud.Event, isDelete bool, noMaskValues bool) (string,
}

// Solve generates a diff and walks the graph.
func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool) (Stats, []error) {
func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool, isJsonOut bool) (Stats, []error, EntityChanges) {
stats := Stats{
CreateOps: &utils.AtomicInt32Counter{},
UpdateOps: &utils.AtomicInt32Counter{},
Expand All @@ -393,31 +407,55 @@ func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool) (Stats,
stats.DeleteOps.Increment(1)
}
}


output := EntityChanges{
Creating: []entityState{},
Updating: []entityState{},
Deleting: []entityState{},
}

errs := sc.Run(ctx, parallelism, func(e crud.Event) (crud.Arg, error) {
var err error
var result crud.Arg

c := e.Obj.(state.ConsoleString)

item := entityState{
OldState: e.Obj,
NewState: e.OldObj,
Name: c.Console(),
}
switch e.Op {
case crud.Create:
diffString, err := generateDiffString(e, false, sc.noMaskValues)
if err != nil {
return nil, err
}
sc.createPrintln("creating", e.Kind, c.Console(), diffString)
if(isJsonOut){
output.Creating = append(output.Creating, item)
}else{
sc.createPrintln("creating", e.Kind, c.Console(), diffString)
}
case crud.Update:
diffString, err := generateDiffString(e, false, sc.noMaskValues)
if err != nil {
return nil, err
}
sc.updatePrintln("updating", e.Kind, c.Console(), diffString)
if(isJsonOut){
output.Updating = append(output.Updating, item)
}else{
sc.updatePrintln("updating", e.Kind, c.Console(), diffString)
}
case crud.Delete:
diffString, err := generateDiffString(e, true, sc.noMaskValues)
if err != nil {
return nil, err
}
sc.deletePrintln("deleting", e.Kind, c.Console(), diffString)
if(isJsonOut){
output.Deleting = append(output.Deleting, item)
}else{
sc.deletePrintln("deleting", e.Kind, c.Console(), diffString)
}
default:
panic("unknown operation " + e.Op.String())
}
Expand All @@ -439,5 +477,5 @@ func (sc *Syncer) Solve(ctx context.Context, parallelism int, dry bool) (Stats,

return result, nil
})
return stats, errs
return stats, errs, output
}

0 comments on commit e6264b7

Please sign in to comment.