Skip to content

CF-3930 : Return structured savepoint schema from create -o json/yaml to match describe/list#3396

Open
Paras Negi (paras-negi-flink) wants to merge 2 commits into
mainfrom
cf-3930-savepoint-create-output-shape
Open

CF-3930 : Return structured savepoint schema from create -o json/yaml to match describe/list#3396
Paras Negi (paras-negi-flink) wants to merge 2 commits into
mainfrom
cf-3930-savepoint-create-output-shape

Conversation

@paras-negi-flink

@paras-negi-flink Paras Negi (paras-negi-flink) commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Release Notes

Breaking Changes

  • NONE

New Features

  • NONE

Bug Fixes

  • confluent flink savepoint create and detached-savepoint create now return the same structured JSON/YAML schema (apiVersion/kind/metadata/spec/status) as describe/list, instead of a flat snake_case shape.

Checklist

  • I have successfully built and used a custom CLI binary, without linter issues from this PR.
  • I have clearly specified in the What section below whether this PR applies to Confluent Cloud, Confluent Platform, or both.
  • I have attached manual CLI verification results or screenshots in the Test & Review section below.
  • I have added appropriate CLI integration or unit tests for any new or updated commands and functionality.
  • I confirm that this PR introduces no breaking changes or backward compatibility issues.
  • I have indicated the potential customer impact if something goes wrong in the Blast Radius section below.
  • I have put checkmarks below confirming that the feature associated with this PR is enabled in:
    • Confluent Cloud prod
    • Confluent Cloud stag
    • Confluent Platform
    • Check this box if the feature is enabled for certain organizations only

What

Confluent Platform (CP Flink / CMF on-prem).

  • savepoint/detached-savepoint create always rendered the flat snake_case struct and ignored -o, while describe/list emit the structured apiVersion/kind/metadata/spec/status shape -- same resource, two schemas.
  • Fix: create now branches on output format like describe/list, reusing the existing convertSdk*ToLocalSavepoint converters. Human/table output is unchanged.

Blast Radius

  • -o json/-o yaml output of the two create commands changes from flat snake_case to the structured shape; scripts reading backoff_limit / creation_timestamp / format must switch to spec.backoffLimit / metadata.creationTimestamp / spec.formatType.
  • No other commands affected; human/table output unchanged.

References

Test & Review

Environment: local CMF cmf-app 2.4-SNAPSHOT (HTTP, --cmf.k8s.enabled=false); CLI built from this branch vs released confluent v4.54.0.

Manual CLI validation: attached in the comment below.

Copilot AI review requested due to automatic review settings July 5, 2026 21:26
@confluent-cla-assistant

Copy link
Copy Markdown

🎉 All Contributor License Agreements have been signed. Ready to merge.
Please push an empty commit if you would like to re-run the checks to verify CLA status for all contributors.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns CMF (on-prem) Flink savepoint create commands’ serialized (-o json|yaml) output with the structured resource schema used by related commands, improving schema consistency for automation.

Changes:

  • Updated flink savepoint create and flink detached-savepoint create to print human/table output only for --output human, and otherwise serialize the structured LocalSavepoint shape.
  • Added integration test cases for savepoint create and detached-savepoint create with --output json|yaml.
  • Added new golden fixtures for the new serialized outputs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/flink/command_savepoint_create.go Branches output by format; uses structured LocalSavepoint for serialized output.
internal/flink/command_detached_savepoint_create.go Branches output by format; uses structured LocalSavepoint for serialized output.
test/flink_onprem_test.go Adds --output json/--output yaml integration cases for both create commands.
test/fixtures/output/flink/savepoint/create-savepoint-json.golden New expected JSON output for savepoint create.
test/fixtures/output/flink/savepoint/create-savepoint-yaml.golden New expected YAML output for savepoint create.
test/fixtures/output/flink/detached-savepoint/create-savepoint-json.golden New expected JSON output for detached-savepoint create.
test/fixtures/output/flink/detached-savepoint/create-savepoint-yaml.golden New expected YAML output for detached-savepoint create.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +131 to +132
localSavepoint := convertSdkSavepointToLocalSavepoint(savepointCreated)
return output.SerializedOutput(cmd, localSavepoint)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please check if the nil check can be handled elegantly using the SDK in some way.

Comment thread test/flink_onprem_test.go
Comment on lines 133 to 140
func (s *CLITestSuite) TestFlinkSavepointCreate() {
tests := []CLITest{
{args: "flink savepoint create savepoint1 --environment default --application application1", fixture: "flink/savepoint/create-savepoint.golden"},
{args: "flink savepoint create savepoint1 --environment default --application application1 --output json", fixture: "flink/savepoint/create-savepoint-json.golden"},
{args: "flink savepoint create savepoint1 --environment default --application application1 --output yaml", fixture: "flink/savepoint/create-savepoint-yaml.golden"},
{args: "flink savepoint create --environment default --application application2", fixture: "flink/savepoint/create-savepoint-no-name.golden"},
{args: "flink savepoint create savepointS --environment default --statement test-stmt", fixture: "flink/savepoint/create-savepoint-statement.golden"},
{args: "flink savepoint create savepointS --environment default --statement test-stmt --path abc/def --format NATIVE --backoff-limit 10", fixture: "flink/savepoint/create-savepoint-statement-values.golden"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if making additional --output yaml makes sense here?

@paras-negi-flink

Copy link
Copy Markdown
Contributor Author

Manual CLI validation

Local CMF (cmf-app 2.4-SNAPSHOT, HTTP, --cmf.k8s.enabled=false). Same detached-savepoint create -o json, released CLI vs this PR.

Before — released confluent v4.54.0 (flat snake_case)

$ confluent --url $CMF flink detached-savepoint create demo --path file:///tmp/sp -o json
{
  "name": "cf3930-cmt-before",
  "path": "file:///tmp/sp-b",
  "format": "CANONICAL",
  "backoff_limit": -1,
  "creation_timestamp": "2026-07-07T05:05:14.063907Z",
  "uid": "9083dcaa-c4f2-4dd4-a3e3-c277bbe3af78"
}

After — this PR (structured, matches describe/list)

$ confluent --url $CMF flink detached-savepoint create demo --path file:///tmp/sp -o json
{
  "apiVersion": "cmf.confluent.io/v1",
  "kind": "Savepoint",
  "metadata": {
    "name": "cf3930-cmt-after",
    "creationTimestamp": "2026-07-07T05:05:14.477077Z",
    "uid": "96f15266-d61c-418d-b415-e68bfaf32cbb",
    "labels": {},
    "annotations": {}
  },
  "spec": {
    "path": "file:///tmp/sp-a",
    "backoffLimit": -1,
    "formatType": "CANONICAL"
  },
  "status": {
    "state": "COMPLETED",
    "path": "file:///tmp/sp-a"
  }
}

@sonarqube-confluent

Copy link
Copy Markdown

@paras-negi-flink
Paras Negi (paras-negi-flink) marked this pull request as ready for review July 7, 2026 06:06
@paras-negi-flink
Paras Negi (paras-negi-flink) requested a review from a team as a code owner July 7, 2026 06:06
Kind: sdkSavepoint.Kind,
Metadata: LocalSavepointMetadata{
Name: *sdkSavepoint.Metadata.Name,
Name: sdkSavepoint.Metadata.GetName(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not:

CreationTimestamp: sdkSavepoint.Metadata.GetCreationTimestamp() for the line below and similar fields?

The idea is try to be consistent across the table everywhere.

Kind: sdkSavepoint.Kind,
Metadata: LocalSavepointMetadata{
Name: *sdkSavepoint.Metadata.Name,
Name: sdkSavepoint.Metadata.GetName(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the above comment and see if we can apply the same idea here.

Comment on lines +131 to +132
localSavepoint := convertSdkSavepointToLocalSavepoint(savepointCreated)
return output.SerializedOutput(cmd, localSavepoint)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please check if the nil check can be handled elegantly using the SDK in some way.

Comment thread test/flink_onprem_test.go
{args: "flink savepoint create --environment default --application application2", fixture: "flink/savepoint/create-savepoint-no-name.golden"},
{args: "flink savepoint create --environment default --application application2 --output json", fixture: "flink/savepoint/create-savepoint-no-name-json.golden"},
{args: "flink savepoint create savepointS --environment default --statement test-stmt", fixture: "flink/savepoint/create-savepoint-statement.golden"},
{args: "flink savepoint create savepointS --environment default --statement test-stmt --output json", fixture: "flink/savepoint/create-savepoint-statement-json.golden"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the optional savepoint name savepointS a typo?

Comment thread test/flink_onprem_test.go
Comment on lines 133 to 140
func (s *CLITestSuite) TestFlinkSavepointCreate() {
tests := []CLITest{
{args: "flink savepoint create savepoint1 --environment default --application application1", fixture: "flink/savepoint/create-savepoint.golden"},
{args: "flink savepoint create savepoint1 --environment default --application application1 --output json", fixture: "flink/savepoint/create-savepoint-json.golden"},
{args: "flink savepoint create savepoint1 --environment default --application application1 --output yaml", fixture: "flink/savepoint/create-savepoint-yaml.golden"},
{args: "flink savepoint create --environment default --application application2", fixture: "flink/savepoint/create-savepoint-no-name.golden"},
{args: "flink savepoint create savepointS --environment default --statement test-stmt", fixture: "flink/savepoint/create-savepoint-statement.golden"},
{args: "flink savepoint create savepointS --environment default --statement test-stmt --path abc/def --format NATIVE --backoff-limit 10", fixture: "flink/savepoint/create-savepoint-statement-values.golden"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if making additional --output yaml makes sense here?

@channingdong

Copy link
Copy Markdown
Contributor

Do we want to update the detach operation as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants