Merge pull request #13188 from srikiz/fix-kops-get-clusters-json-output

[Issue-12293] Fix json output to keep it consistent for single or multiple objects
This commit is contained in:
Kubernetes Prow Robot 2022-02-09 03:00:18 -08:00 committed by GitHub
commit 219bc8d54d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 32 additions and 22 deletions

View File

@ -720,7 +720,7 @@ func RunCreateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Cr
}
return nil
case OutputJSON:
if err := fullOutputJSON(out, obj...); err != nil {
if err := fullOutputJSON(out, true, obj...); err != nil {
return fmt.Errorf("error writing cluster json to stdout: %v", err)
}
return nil

View File

@ -221,7 +221,7 @@ func RunCreateInstanceGroup(ctx context.Context, f *util.Factory, out io.Writer,
}
return nil
case OutputJSON:
if err := fullOutputJSON(out, ig); err != nil {
if err := fullOutputJSON(out, true, ig); err != nil {
return fmt.Errorf("error writing cluster json to stdout: %v", err)
}
return nil

View File

@ -158,7 +158,7 @@ func RunGet(ctx context.Context, f commandutils.Factory, out io.Writer, options
return nil
case OutputJSON:
if err := fullOutputJSON(out, allObjects...); err != nil {
if err := fullOutputJSON(out, false, allObjects...); err != nil {
return fmt.Errorf("error writing json to stdout: %v", err)
}
return nil

View File

@ -123,17 +123,11 @@ func RunGetClusters(ctx context.Context, f commandutils.Factory, out io.Writer,
return err
}
singleClusterSelected := false
var clusterList []*kopsapi.Cluster
if len(options.ClusterNames) != 1 {
list, err := client.ListClusters(ctx, metav1.ListOptions{})
if err != nil {
return err
}
for i := range list.Items {
clusterList = append(clusterList, &list.Items[i])
}
} else {
if len(options.ClusterNames) == 1 {
// Optimization - avoid fetching all clusters if we're only querying one
singleClusterSelected = true
cluster, err := client.GetCluster(ctx, options.ClusterNames[0])
if err != nil {
if !apierrors.IsNotFound(err) {
@ -142,6 +136,14 @@ func RunGetClusters(ctx context.Context, f commandutils.Factory, out io.Writer,
} else {
clusterList = append(clusterList, cluster)
}
} else {
list, err := client.ListClusters(ctx, metav1.ListOptions{})
if err != nil {
return err
}
for i := range list.Items {
clusterList = append(clusterList, &list.Items[i])
}
}
clusters, err := filterClustersByName(options.ClusterNames, clusterList)
@ -176,7 +178,11 @@ func RunGetClusters(ctx context.Context, f commandutils.Factory, out io.Writer,
case OutputYaml:
return fullOutputYAML(out, obj...)
case OutputJSON:
return fullOutputJSON(out, obj...)
// if singleClusterSelected is true, only a single object is returned
// otherwise to keep it consistent, always returns an array.
// Ex: kops get clusters -ojson should will always return an array (even if 1 cluster is available)
// kops get cluster test.example.com -o json will return a single object (since a specific cluster is selected)
return fullOutputJSON(out, singleClusterSelected, obj...)
default:
return fmt.Errorf("Unknown output format: %q", options.Output)
}
@ -227,12 +233,10 @@ func clusterOutputTable(clusters []*kopsapi.Cluster, out io.Writer) error {
return t.Render(clusters, out, "NAME", "CLOUD", "ZONES")
}
// fullOutputJson outputs the marshalled JSON of a list of clusters and instance groups. It will handle
// fullOutputJSON outputs the marshalled JSON of a list of clusters and instance groups. It will handle
// nils for clusters and instanceGroups slices.
func fullOutputJSON(out io.Writer, args ...runtime.Object) error {
argsLen := len(args)
if argsLen > 1 {
func fullOutputJSON(out io.Writer, singleObject bool, args ...runtime.Object) error {
if !singleObject {
if _, err := fmt.Fprint(out, "["); err != nil {
return err
}
@ -249,7 +253,7 @@ func fullOutputJSON(out io.Writer, args ...runtime.Object) error {
}
}
if argsLen > 1 {
if !singleObject {
if _, err := fmt.Fprint(out, "]"); err != nil {
return err
}
@ -258,7 +262,7 @@ func fullOutputJSON(out io.Writer, args ...runtime.Object) error {
return nil
}
// fullOutputJson outputs the marshalled JSON of a list of clusters and instance groups. It will handle
// fullOutputYAML outputs the marshalled JSON of a list of clusters and instance groups. It will handle
// nils for clusters and instanceGroups slices.
func fullOutputYAML(out io.Writer, args ...runtime.Object) error {
for i, obj := range args {

View File

@ -113,8 +113,12 @@ func RunGetInstanceGroups(ctx context.Context, f commandutils.Factory, out io.Wr
return err
}
singleObject := false
if len(instancegroups) == 0 {
return fmt.Errorf("no InstanceGroup objects found")
} else if len(instancegroups) == 1 {
singleObject = true
}
var obj []runtime.Object
@ -130,7 +134,7 @@ func RunGetInstanceGroups(ctx context.Context, f commandutils.Factory, out io.Wr
case OutputYaml:
return fullOutputYAML(out, obj...)
case OutputJSON:
return fullOutputJSON(out, obj...)
return fullOutputJSON(out, singleObject, obj...)
default:
return fmt.Errorf("unknown output format: %q", options.Output)
}

View File

@ -332,7 +332,7 @@ func RunToolboxInstanceSelector(ctx context.Context, f *util.Factory, out io.Wri
return fmt.Errorf("error writing cluster yaml to stdout: %v", err)
}
case OutputJSON:
if err := fullOutputJSON(out, ig); err != nil {
if err := fullOutputJSON(out, true, ig); err != nil {
return fmt.Errorf("error writing cluster json to stdout: %v", err)
}
default:

View File

@ -64,6 +64,8 @@ It is recommended to keep using the `v1alpha2` API version.
* The `kops rolling-update cluster` command has a new `--drain-timeout` flag for specifying the maximum amount of time to wait when attempting to drain a node. Previously, rolling-updates would attempt to drain a node for an indefinite amount of time. If `--drain-timeout` is not specified, a default of 15 minutes is applied.
* Fix inconsistent output of `kops get clusters -ojson`. This will now always return a list (irrespective of a single or multiple clusters) to keep the format consistent. However, note that `kops get cluster dev.example.com -ojson` will continue to work as previously, and will return a single object.
# Full change list since 1.22.0 release