Add structured JSON output for velero restore describe command (#9983)
Run the E2E test on kind / setup-test-matrix (push) Failing after 4s
e2e-test-kind.yaml / extract (push) Failing after 9s
Run the E2E test on kind / get-go-version (push) Failing after 10s
Run the E2E test on kind / build (push) Skipped
Run the E2E test on kind / run-e2e-test (push) Skipped
push.yml / extract (push) Failing after 5s
Main CI / get-go-version (push) Failing after 6s
Main CI / Build (push) Skipped

* Add structured JSON output for velero restore describe command

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Add changelog for PR 9983

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Fix CSI snapshot restore JSON output to distinguish snapshot vs dataMovement type

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Remove the redundant details wrapper key from podVolumeRestores so phase counts sit flat alongside uploaderType, matching the plaintext output structure.

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Add missing resourcePolicy to json struct

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Fix linter issue

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* fix codecoverage

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Handle nil CSI snapshot fields in restore JSON describe

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

* Fix lint issue

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>

---------

Signed-off-by: Prasad Joshi <prajoshi@redhat.com>
Co-authored-by: lyndon-li <98304688+Lyndon-Li@users.noreply.github.com>
Co-authored-by: Tiger Kaovilai <tkaovila@redhat.com>
This commit is contained in:
Prasad Joshi
2026-09-03 14:36:51 -04:00
committed by GitHub
co-authored by lyndon-li Tiger Kaovilai
parent a96f567f38
commit 31333f7610
5 changed files with 1524 additions and 6 deletions
+2 -2
View File
@@ -56,7 +56,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
cmd.CheckError(err)
if outputFormat != "plaintext" && outputFormat != "json" {
cmd.CheckError(fmt.Errorf("invalid output format '%s'. valid value are 'plaintext, json'", outputFormat))
cmd.CheckError(fmt.Errorf("invalid output format '%s'. valid values are 'plaintext' and 'json'", outputFormat))
}
backups := new(velerov1api.BackupList)
@@ -118,7 +118,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
c.Flags().BoolVar(&details, "details", details, "Display additional detail in the command output.")
c.Flags().BoolVar(&insecureSkipTLSVerify, "insecure-skip-tls-verify", insecureSkipTLSVerify, "If true, the object store's TLS certificate will not be checked for validity. This is insecure and susceptible to man-in-the-middle attacks. Not recommended for production.")
c.Flags().StringVar(&caCertFile, "cacert", caCertFile, "Path to a certificate bundle to use when verifying TLS connections. If not specified, the CA certificate from the BackupStorageLocation will be used if available.")
c.Flags().StringVarP(&outputFormat, "output", "o", outputFormat, "Output display format. Valid formats are 'plaintext, json'. 'json' only applies to a single backup")
c.Flags().StringVarP(&outputFormat, "output", "o", outputFormat, "Output display format. Valid formats are 'plaintext' and 'json'. 'json' only applies to a single backup")
return c
}
+17 -4
View File
@@ -39,6 +39,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
listOptions metav1.ListOptions
details bool
insecureSkipTLSVerify bool
outputFormat = "plaintext"
)
config, err := client.LoadConfig()
@@ -54,6 +55,10 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
kbClient, err := f.KubebuilderClient()
cmd.CheckError(err)
if outputFormat != "plaintext" && outputFormat != "json" {
cmd.CheckError(fmt.Errorf("invalid output format '%s'. valid values are 'plaintext' and 'json'", outputFormat))
}
restoreList := new(velerov1api.RestoreList)
if len(args) > 0 {
for _, name := range args {
@@ -81,12 +86,19 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
fmt.Fprintf(os.Stderr, "error getting PodVolumeRestores for restore %s: %v\n", restore.Name, err)
}
s := output.DescribeRestore(context.Background(), kbClient, &restoreList.Items[i], podVolumeRestoreList.Items, details, insecureSkipTLSVerify, caCertFile)
if first {
first = false
// structured output only applies to a single restore in case of OOM
// To describe a list of restores in structured format, iterate and describe one at a time.
if len(restoreList.Items) == 1 && outputFormat != "plaintext" {
s := output.DescribeRestoreInSF(context.Background(), kbClient, &restoreList.Items[i], podVolumeRestoreList.Items, details, insecureSkipTLSVerify, caCertFile, outputFormat)
fmt.Print(s)
} else {
fmt.Printf("\n\n%s", s)
s := output.DescribeRestore(context.Background(), kbClient, &restoreList.Items[i], podVolumeRestoreList.Items, details, insecureSkipTLSVerify, caCertFile)
if first {
first = false
fmt.Print(s)
} else {
fmt.Printf("\n\n%s", s)
}
}
}
cmd.CheckError(err)
@@ -98,6 +110,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
c.Flags().BoolVar(&details, "details", details, "Display additional detail in the command output.")
c.Flags().BoolVar(&insecureSkipTLSVerify, "insecure-skip-tls-verify", insecureSkipTLSVerify, "If true, the object store's TLS certificate will not be checked for validity. This is insecure and susceptible to man-in-the-middle attacks. Not recommended for production.")
c.Flags().StringVar(&caCertFile, "cacert", caCertFile, "Path to a certificate bundle to use when verifying TLS connections.")
c.Flags().StringVarP(&outputFormat, "output", "o", outputFormat, "Output display format. Valid formats are 'plaintext' and 'json'. 'json' only applies to a single restore")
return c
}