From 06f8e027189031b26b77faf3c485c3310a5d5a4a Mon Sep 17 00:00:00 2001 From: Paras Negi Date: Sat, 11 Apr 2026 08:12:35 +0530 Subject: [PATCH 1/2] Add cli command for ApplicationEvent list --- internal/flink/command_application.go | 1 + internal/flink/command_application_event.go | 69 +++++++++++++++++ .../flink/command_application_event_list.go | 70 ++++++++++++++++++ pkg/flink/cmf_rest_client.go | 18 +++++ .../application/event-list-app-missing.golden | 18 +++++ .../flink/application/event-list-empty.golden | 1 + .../application/event-list-help-onprem.golden | 18 +++++ .../flink/application/event-list-human.golden | 6 ++ .../flink/application/event-list-json.golden | 28 +++++++ .../event-list-missing-flags.golden | 18 +++++ .../flink/application/event-list-yaml.golden | 18 +++++ .../application/event/help-onprem.golden | 14 ++++ .../application/event/list-help-onprem.golden | 18 +++++ .../flink/application/help-onprem.golden | 1 + test/flink_onprem_test.go | 15 ++++ test/test-server/flink_onprem_handler.go | 74 +++++++++++++++++++ test/test-server/flink_onprem_router.go | 1 + 17 files changed, 388 insertions(+) create mode 100644 internal/flink/command_application_event.go create mode 100644 internal/flink/command_application_event_list.go create mode 100644 test/fixtures/output/flink/application/event-list-app-missing.golden create mode 100644 test/fixtures/output/flink/application/event-list-empty.golden create mode 100644 test/fixtures/output/flink/application/event-list-help-onprem.golden create mode 100644 test/fixtures/output/flink/application/event-list-human.golden create mode 100644 test/fixtures/output/flink/application/event-list-json.golden create mode 100644 test/fixtures/output/flink/application/event-list-missing-flags.golden create mode 100644 test/fixtures/output/flink/application/event-list-yaml.golden create mode 100644 test/fixtures/output/flink/application/event/help-onprem.golden create mode 100644 test/fixtures/output/flink/application/event/list-help-onprem.golden diff --git a/internal/flink/command_application.go b/internal/flink/command_application.go index 3cc1e9cf58..8f5a11006b 100644 --- a/internal/flink/command_application.go +++ b/internal/flink/command_application.go @@ -33,6 +33,7 @@ func (c *command) newApplicationCommand() *cobra.Command { cmd.AddCommand(c.newApplicationCreateCommand()) cmd.AddCommand(c.newApplicationDeleteCommand()) cmd.AddCommand(c.newApplicationDescribeCommand()) + cmd.AddCommand(c.newApplicationEventCommand()) cmd.AddCommand(c.newApplicationListCommand()) cmd.AddCommand(c.newApplicationUpdateCommand()) cmd.AddCommand(c.newApplicationWebUiForwardCommand()) diff --git a/internal/flink/command_application_event.go b/internal/flink/command_application_event.go new file mode 100644 index 0000000000..e70e2b79fa --- /dev/null +++ b/internal/flink/command_application_event.go @@ -0,0 +1,69 @@ +package flink + +import ( + "github.com/spf13/cobra" + + cmfsdk "github.com/confluentinc/cmf-sdk-go/v1" + + pcmd "github.com/confluentinc/cli/v4/pkg/cmd" +) + +type flinkApplicationEventOut struct { + Name string `human:"Name" serialized:"name"` + Type string `human:"Type" serialized:"type"` + Timestamp string `human:"Timestamp" serialized:"timestamp"` + Instance string `human:"Instance" serialized:"instance"` + Message string `human:"Message" serialized:"message"` +} + +func (c *command) newApplicationEventCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "event", + Short: "Manage Flink application events.", + Annotations: map[string]string{pcmd.RunRequirement: pcmd.RequireCloudLogout}, + } + + cmd.AddCommand(c.newApplicationEventListCommand()) + + return cmd +} + +type LocalFlinkApplicationEvent struct { + ApiVersion string `json:"apiVersion" yaml:"apiVersion"` + Kind string `json:"kind" yaml:"kind"` + Metadata LocalEventMetadata `json:"metadata" yaml:"metadata"` + Status LocalEventStatus `json:"status" yaml:"status"` +} + +type LocalEventMetadata struct { + Name *string `json:"name,omitempty" yaml:"name,omitempty"` + Uid *string `json:"uid,omitempty" yaml:"uid,omitempty"` + CreationTimestamp *string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` + FlinkApplicationInstance *string `json:"flinkApplicationInstance,omitempty" yaml:"flinkApplicationInstance,omitempty"` + Labels *map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Annotations *map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` +} + +type LocalEventStatus struct { + Message *string `json:"message,omitempty" yaml:"message,omitempty"` + Type *string `json:"type,omitempty" yaml:"type,omitempty"` +} + +func convertSdkEventToLocalEvent(sdkEvent cmfsdk.FlinkApplicationEvent) LocalFlinkApplicationEvent { + return LocalFlinkApplicationEvent{ + ApiVersion: sdkEvent.ApiVersion, + Kind: sdkEvent.Kind, + Metadata: LocalEventMetadata{ + Name: sdkEvent.Metadata.Name, + Uid: sdkEvent.Metadata.Uid, + CreationTimestamp: sdkEvent.Metadata.CreationTimestamp, + FlinkApplicationInstance: sdkEvent.Metadata.FlinkApplicationInstance, + Labels: sdkEvent.Metadata.Labels, + Annotations: sdkEvent.Metadata.Annotations, + }, + Status: LocalEventStatus{ + Message: sdkEvent.Status.Message, + Type: sdkEvent.Status.Type, + }, + } +} diff --git a/internal/flink/command_application_event_list.go b/internal/flink/command_application_event_list.go new file mode 100644 index 0000000000..6270f7d7c3 --- /dev/null +++ b/internal/flink/command_application_event_list.go @@ -0,0 +1,70 @@ +package flink + +import ( + "github.com/spf13/cobra" + + pcmd "github.com/confluentinc/cli/v4/pkg/cmd" + "github.com/confluentinc/cli/v4/pkg/output" +) + +func (c *command) newApplicationEventListCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "list", + Short: "List Flink application events.", + Args: cobra.NoArgs, + RunE: c.applicationEventList, + } + + cmd.Flags().String("environment", "", "Name of the Flink environment.") + cmd.Flags().String("application", "", "Name of the Flink application.") + addCmfFlagSet(cmd) + pcmd.AddOutputFlag(cmd) + + cobra.CheckErr(cmd.MarkFlagRequired("environment")) + cobra.CheckErr(cmd.MarkFlagRequired("application")) + + return cmd +} + +func (c *command) applicationEventList(cmd *cobra.Command, _ []string) error { + environment, err := cmd.Flags().GetString("environment") + if err != nil { + return err + } + + application, err := cmd.Flags().GetString("application") + if err != nil { + return err + } + + client, err := c.GetCmfClient(cmd) + if err != nil { + return err + } + + events, err := client.ListApplicationEvents(c.createContext(), environment, application) + if err != nil { + return err + } + + if output.GetFormat(cmd) == output.Human { + list := output.NewList(cmd) + for _, event := range events { + list.Add(&flinkApplicationEventOut{ + Name: event.Metadata.GetName(), + Type: event.Status.GetType(), + Timestamp: event.Metadata.GetCreationTimestamp(), + Instance: event.Metadata.GetFlinkApplicationInstance(), + Message: event.Status.GetMessage(), + }) + } + return list.Print() + } + + localEvents := make([]LocalFlinkApplicationEvent, 0, len(events)) + for _, sdkEvent := range events { + localEvents = append(localEvents, convertSdkEventToLocalEvent(sdkEvent)) + } + + return output.SerializedOutput(cmd, localEvents) +} diff --git a/pkg/flink/cmf_rest_client.go b/pkg/flink/cmf_rest_client.go index 97d68971eb..0c1ffa421d 100644 --- a/pkg/flink/cmf_rest_client.go +++ b/pkg/flink/cmf_rest_client.go @@ -228,6 +228,24 @@ func (cmfClient *CmfRestClient) UpdateApplication(ctx context.Context, environme return outputApplication, nil } +func (cmfClient *CmfRestClient) ListApplicationEvents(ctx context.Context, environment, application string) ([]cmfsdk.FlinkApplicationEvent, error) { + events := make([]cmfsdk.FlinkApplicationEvent, 0) + var currentPageNumber int32 = 0 + const pageSize = 100 + done := false + + for !done { + eventsPage, httpResponse, err := cmfClient.FlinkApplicationsApi.GetApplicationEvents(ctx, environment, application).Page(currentPageNumber).Size(pageSize).Execute() + if parsedErr := parseSdkError(httpResponse, err); parsedErr != nil { + return nil, fmt.Errorf(`failed to list events for application "%s" in the environment "%s": %s`, application, environment, parsedErr) + } + events = append(events, eventsPage.GetItems()...) + currentPageNumber, done = extractPageOptions(len(eventsPage.GetItems()), currentPageNumber) + } + + return events, nil +} + // CreateEnvironment Create an environment. // Internally, since the call for Create and Update is the same, we check if the environment exists before creation. func (cmfClient *CmfRestClient) CreateEnvironment(ctx context.Context, postEnvironment cmfsdk.PostEnvironment) (cmfsdk.Environment, error) { diff --git a/test/fixtures/output/flink/application/event-list-app-missing.golden b/test/fixtures/output/flink/application/event-list-app-missing.golden new file mode 100644 index 0000000000..7f894127c6 --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-app-missing.golden @@ -0,0 +1,18 @@ +Error: required flag(s) "application" not set +Usage: + confluent flink application event list [flags] + +Flags: + --environment string REQUIRED: Name of the Flink environment. + --application string REQUIRED: Name of the Flink application. + --url string Base URL of the Confluent Manager for Apache Flink (CMF). Environment variable "CONFLUENT_CMF_URL" may be set in place of this flag. + --client-key-path string Path to client private key for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_KEY_PATH" may be set in place of this flag. + --client-cert-path string Path to client cert to be verified by Confluent Manager for Apache Flink. Include for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_CERT_PATH" may be set in place of this flag. + --certificate-authority-path string Path to a PEM-encoded Certificate Authority to verify the Confluent Manager for Apache Flink connection. Environment variable "CONFLUENT_CMF_CERTIFICATE_AUTHORITY_PATH" may be set in place of this flag. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + +Global Flags: + -h, --help Show help for this command. + --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. + -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). + diff --git a/test/fixtures/output/flink/application/event-list-empty.golden b/test/fixtures/output/flink/application/event-list-empty.golden new file mode 100644 index 0000000000..167bb27ed9 --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-empty.golden @@ -0,0 +1 @@ +None found. diff --git a/test/fixtures/output/flink/application/event-list-help-onprem.golden b/test/fixtures/output/flink/application/event-list-help-onprem.golden new file mode 100644 index 0000000000..6c301ae514 --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-help-onprem.golden @@ -0,0 +1,18 @@ +List Flink application events. + +Usage: + confluent flink application event list [flags] + +Flags: + --environment string REQUIRED: Name of the Flink environment. + --application string REQUIRED: Name of the Flink application. + --url string Base URL of the Confluent Manager for Apache Flink (CMF). Environment variable "CONFLUENT_CMF_URL" may be set in place of this flag. + --client-key-path string Path to client private key for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_KEY_PATH" may be set in place of this flag. + --client-cert-path string Path to client cert to be verified by Confluent Manager for Apache Flink. Include for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_CERT_PATH" may be set in place of this flag. + --certificate-authority-path string Path to a PEM-encoded Certificate Authority to verify the Confluent Manager for Apache Flink connection. Environment variable "CONFLUENT_CMF_CERTIFICATE_AUTHORITY_PATH" may be set in place of this flag. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + +Global Flags: + -h, --help Show help for this command. + --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. + -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). diff --git a/test/fixtures/output/flink/application/event-list-human.golden b/test/fixtures/output/flink/application/event-list-human.golden new file mode 100644 index 0000000000..82c93e3674 --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-human.golden @@ -0,0 +1,6 @@ + Name | Type | Timestamp | Instance | Message +------------+---------+----------------------+----------------------------------+--------------------------------- + event-001 | Normal | 2024-01-15T10:30:00Z | default-application-1-instance-1 | Application started + | | | | successfully + event-002 | Warning | 2024-01-15T10:31:00Z | default-application-1-instance-1 | Application restarting due to + | | | | failure diff --git a/test/fixtures/output/flink/application/event-list-json.golden b/test/fixtures/output/flink/application/event-list-json.golden new file mode 100644 index 0000000000..a1bbb1e28d --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-json.golden @@ -0,0 +1,28 @@ +[ + { + "apiVersion": "cmf.confluent.io/v1alpha1", + "kind": "FlinkApplicationEvent", + "metadata": { + "name": "event-001", + "creationTimestamp": "2024-01-15T10:30:00Z", + "flinkApplicationInstance": "default-application-1-instance-1" + }, + "status": { + "message": "Application started successfully", + "type": "Normal" + } + }, + { + "apiVersion": "cmf.confluent.io/v1alpha1", + "kind": "FlinkApplicationEvent", + "metadata": { + "name": "event-002", + "creationTimestamp": "2024-01-15T10:31:00Z", + "flinkApplicationInstance": "default-application-1-instance-1" + }, + "status": { + "message": "Application restarting due to failure", + "type": "Warning" + } + } +] diff --git a/test/fixtures/output/flink/application/event-list-missing-flags.golden b/test/fixtures/output/flink/application/event-list-missing-flags.golden new file mode 100644 index 0000000000..a282b8202a --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-missing-flags.golden @@ -0,0 +1,18 @@ +Error: required flag(s) "environment", "application" not set +Usage: + confluent flink application event list [flags] + +Flags: + --environment string REQUIRED: Name of the Flink environment. + --application string REQUIRED: Name of the Flink application. + --url string Base URL of the Confluent Manager for Apache Flink (CMF). Environment variable "CONFLUENT_CMF_URL" may be set in place of this flag. + --client-key-path string Path to client private key for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_KEY_PATH" may be set in place of this flag. + --client-cert-path string Path to client cert to be verified by Confluent Manager for Apache Flink. Include for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_CERT_PATH" may be set in place of this flag. + --certificate-authority-path string Path to a PEM-encoded Certificate Authority to verify the Confluent Manager for Apache Flink connection. Environment variable "CONFLUENT_CMF_CERTIFICATE_AUTHORITY_PATH" may be set in place of this flag. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + +Global Flags: + -h, --help Show help for this command. + --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. + -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). + diff --git a/test/fixtures/output/flink/application/event-list-yaml.golden b/test/fixtures/output/flink/application/event-list-yaml.golden new file mode 100644 index 0000000000..5a7504aec7 --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-yaml.golden @@ -0,0 +1,18 @@ +- apiVersion: cmf.confluent.io/v1alpha1 + kind: FlinkApplicationEvent + metadata: + name: event-001 + creationTimestamp: "2024-01-15T10:30:00Z" + flinkApplicationInstance: default-application-1-instance-1 + status: + message: Application started successfully + type: Normal +- apiVersion: cmf.confluent.io/v1alpha1 + kind: FlinkApplicationEvent + metadata: + name: event-002 + creationTimestamp: "2024-01-15T10:31:00Z" + flinkApplicationInstance: default-application-1-instance-1 + status: + message: Application restarting due to failure + type: Warning diff --git a/test/fixtures/output/flink/application/event/help-onprem.golden b/test/fixtures/output/flink/application/event/help-onprem.golden new file mode 100644 index 0000000000..4c6057d2fc --- /dev/null +++ b/test/fixtures/output/flink/application/event/help-onprem.golden @@ -0,0 +1,14 @@ +Manage Flink application events. + +Usage: + confluent flink application event [command] + +Available Commands: + list List Flink application events. + +Global Flags: + -h, --help Show help for this command. + --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. + -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). + +Use "confluent flink application event [command] --help" for more information about a command. diff --git a/test/fixtures/output/flink/application/event/list-help-onprem.golden b/test/fixtures/output/flink/application/event/list-help-onprem.golden new file mode 100644 index 0000000000..6c301ae514 --- /dev/null +++ b/test/fixtures/output/flink/application/event/list-help-onprem.golden @@ -0,0 +1,18 @@ +List Flink application events. + +Usage: + confluent flink application event list [flags] + +Flags: + --environment string REQUIRED: Name of the Flink environment. + --application string REQUIRED: Name of the Flink application. + --url string Base URL of the Confluent Manager for Apache Flink (CMF). Environment variable "CONFLUENT_CMF_URL" may be set in place of this flag. + --client-key-path string Path to client private key for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_KEY_PATH" may be set in place of this flag. + --client-cert-path string Path to client cert to be verified by Confluent Manager for Apache Flink. Include for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_CERT_PATH" may be set in place of this flag. + --certificate-authority-path string Path to a PEM-encoded Certificate Authority to verify the Confluent Manager for Apache Flink connection. Environment variable "CONFLUENT_CMF_CERTIFICATE_AUTHORITY_PATH" may be set in place of this flag. + -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") + +Global Flags: + -h, --help Show help for this command. + --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. + -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). diff --git a/test/fixtures/output/flink/application/help-onprem.golden b/test/fixtures/output/flink/application/help-onprem.golden index fd5615fe45..ca36d6b8d2 100644 --- a/test/fixtures/output/flink/application/help-onprem.golden +++ b/test/fixtures/output/flink/application/help-onprem.golden @@ -10,6 +10,7 @@ Available Commands: create Create a Flink application. delete Delete one or more Flink applications. describe Describe a Flink application. + event Manage Flink application events. list List Flink applications. update Update a Flink application. web-ui-forward Forward the web UI of a Flink application. diff --git a/test/flink_onprem_test.go b/test/flink_onprem_test.go index 5536f0a14c..bfd857e9a5 100644 --- a/test/flink_onprem_test.go +++ b/test/flink_onprem_test.go @@ -39,6 +39,21 @@ func (s *CLITestSuite) TestFlinkApplicationList() { runIntegrationTestsWithMultipleAuth(s, tests) } +func (s *CLITestSuite) TestFlinkApplicationEventList() { + tests := []CLITest{ + // failure scenarios + {args: "flink application event list", fixture: "flink/application/event-list-missing-flags.golden", exitCode: 1}, + {args: "flink application event list --environment default", fixture: "flink/application/event-list-app-missing.golden", exitCode: 1}, + // success scenarios + {args: "flink application event list --environment test --application non-existent", fixture: "flink/application/event-list-empty.golden"}, + {args: "flink application event list --environment default --application default-application-1 --output human", fixture: "flink/application/event-list-human.golden"}, + {args: "flink application event list --environment default --application default-application-1 --output json", fixture: "flink/application/event-list-json.golden"}, + {args: "flink application event list --environment default --application default-application-1 --output yaml", fixture: "flink/application/event-list-yaml.golden"}, + } + + runIntegrationTestsWithMultipleAuth(s, tests) +} + func (s *CLITestSuite) TestFlinkApplicationDelete() { tests := []CLITest{ // failure scenarios diff --git a/test/test-server/flink_onprem_handler.go b/test/test-server/flink_onprem_handler.go index 3089876db8..4183cf760f 100644 --- a/test/test-server/flink_onprem_handler.go +++ b/test/test-server/flink_onprem_handler.go @@ -445,6 +445,80 @@ func handleCmfEnvironment(t *testing.T) http.HandlerFunc { } } +// Handler for "cmf/api/v1alpha1/environments/{envName}/applications/{appName}/events" +func handleCmfApplicationEvents(t *testing.T) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + handleLoginType(t, r) + + vars := mux.Vars(r) + envName := vars["envName"] + appName := vars["appName"] + + if r.Method != http.MethodGet { + require.Fail(t, fmt.Sprintf("Unexpected method %s", r.Method)) + return + } + + if envName != "default" && envName != "test" { + http.Error(w, "Environment not found", http.StatusNotFound) + return + } + + eventsPage := map[string]interface{}{ + "items": []cmfsdk.FlinkApplicationEvent{}, + } + + page := r.URL.Query().Get("page") + + if envName == "default" && appName == "default-application-1" && page == "0" { + timestamp1 := "2024-01-15T10:30:00Z" + timestamp2 := "2024-01-15T10:31:00Z" + instance := "default-application-1-instance-1" + eventType1 := "Normal" + eventType2 := "Warning" + message1 := "Application started successfully" + message2 := "Application restarting due to failure" + name1 := "event-001" + name2 := "event-002" + + events := []cmfsdk.FlinkApplicationEvent{ + { + ApiVersion: "cmf.confluent.io/v1alpha1", + Kind: "FlinkApplicationEvent", + Metadata: cmfsdk.EventMetadata{ + Name: &name1, + CreationTimestamp: ×tamp1, + FlinkApplicationInstance: &instance, + }, + Status: cmfsdk.EventStatus{ + Type: &eventType1, + Message: &message1, + }, + }, + { + ApiVersion: "cmf.confluent.io/v1alpha1", + Kind: "FlinkApplicationEvent", + Metadata: cmfsdk.EventMetadata{ + Name: &name2, + CreationTimestamp: ×tamp2, + FlinkApplicationInstance: &instance, + }, + Status: cmfsdk.EventStatus{ + Type: &eventType2, + Message: &message2, + }, + }, + } + eventsPage = map[string]interface{}{ + "items": events, + } + } + + err := json.NewEncoder(w).Encode(eventsPage) + require.NoError(t, err) + } +} + // Handler for "cmf/api/v1/environments/{environment}/applications" // Used by list, create and update applications. func handleCmfApplications(t *testing.T) http.HandlerFunc { diff --git a/test/test-server/flink_onprem_router.go b/test/test-server/flink_onprem_router.go index 2267f01d5a..569bfe2af2 100644 --- a/test/test-server/flink_onprem_router.go +++ b/test/test-server/flink_onprem_router.go @@ -11,6 +11,7 @@ var flinkRoutes = []route{ {"/cmf/api/v1/catalogs/kafka/{catName}", handleCmfCatalog}, {"/cmf/api/v1/environments/{environment}/applications", handleCmfApplications}, {"/cmf/api/v1/environments/{environment}/applications/{application}", handleCmfApplication}, + {"/cmf/api/v1alpha1/environments/{envName}/applications/{appName}/events", handleCmfApplicationEvents}, {"/cmf/api/v1/environments", handleCmfEnvironments}, {"/cmf/api/v1/environments/{environment}", handleCmfEnvironment}, {"/cmf/api/v1/environments/{environment}/compute-pools", handleCmfComputePools}, From be210a1ae5c21cbca31da89aa20fa609011c590f Mon Sep 17 00:00:00 2001 From: Paras Negi Date: Sat, 11 Apr 2026 08:51:49 +0530 Subject: [PATCH 2/2] Fix suggested by copilot and claude review --- internal/flink/command_application_event.go | 21 ---------------- internal/flink/local_types.go | 24 +++++++++++++++++++ .../application/event-list-help-onprem.golden | 18 -------------- .../event-list-non-existent-app.golden | 1 + .../event-list-non-existent-env.golden | 1 + test/flink_onprem_test.go | 2 ++ test/test-server/flink_onprem_handler.go | 11 +++++++++ 7 files changed, 39 insertions(+), 39 deletions(-) delete mode 100644 test/fixtures/output/flink/application/event-list-help-onprem.golden create mode 100644 test/fixtures/output/flink/application/event-list-non-existent-app.golden create mode 100644 test/fixtures/output/flink/application/event-list-non-existent-env.golden diff --git a/internal/flink/command_application_event.go b/internal/flink/command_application_event.go index e70e2b79fa..168b64b022 100644 --- a/internal/flink/command_application_event.go +++ b/internal/flink/command_application_event.go @@ -28,27 +28,6 @@ func (c *command) newApplicationEventCommand() *cobra.Command { return cmd } -type LocalFlinkApplicationEvent struct { - ApiVersion string `json:"apiVersion" yaml:"apiVersion"` - Kind string `json:"kind" yaml:"kind"` - Metadata LocalEventMetadata `json:"metadata" yaml:"metadata"` - Status LocalEventStatus `json:"status" yaml:"status"` -} - -type LocalEventMetadata struct { - Name *string `json:"name,omitempty" yaml:"name,omitempty"` - Uid *string `json:"uid,omitempty" yaml:"uid,omitempty"` - CreationTimestamp *string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` - FlinkApplicationInstance *string `json:"flinkApplicationInstance,omitempty" yaml:"flinkApplicationInstance,omitempty"` - Labels *map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - Annotations *map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` -} - -type LocalEventStatus struct { - Message *string `json:"message,omitempty" yaml:"message,omitempty"` - Type *string `json:"type,omitempty" yaml:"type,omitempty"` -} - func convertSdkEventToLocalEvent(sdkEvent cmfsdk.FlinkApplicationEvent) LocalFlinkApplicationEvent { return LocalFlinkApplicationEvent{ ApiVersion: sdkEvent.ApiVersion, diff --git a/internal/flink/local_types.go b/internal/flink/local_types.go index 19e0b756d9..5598846717 100644 --- a/internal/flink/local_types.go +++ b/internal/flink/local_types.go @@ -119,6 +119,30 @@ type LocalFlinkApplication struct { Status *map[string]interface{} `json:"status,omitempty" yaml:"status,omitempty"` } +type LocalFlinkApplicationEvent struct { + ApiVersion string `json:"apiVersion" yaml:"apiVersion"` + Kind string `json:"kind" yaml:"kind"` + Metadata LocalEventMetadata `json:"metadata" yaml:"metadata"` + Status LocalEventStatus `json:"status" yaml:"status"` +} + +type LocalEventMetadata struct { + Name *string `json:"name,omitempty" yaml:"name,omitempty"` + Uid *string `json:"uid,omitempty" yaml:"uid,omitempty"` + CreationTimestamp *string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` + FlinkApplicationInstance *string `json:"flinkApplicationInstance,omitempty" yaml:"flinkApplicationInstance,omitempty"` + Labels *map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Annotations *map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` +} + +// LocalEventStatus maps the SDK EventStatus but intentionally omits the Data field. +// Data is a oneOf union type (EventDataJobException | EventDataNewStatus) that does not +// map cleanly to a simple local struct and is not needed for the CLI list output. +type LocalEventStatus struct { + Message *string `json:"message,omitempty" yaml:"message,omitempty"` + Type *string `json:"type,omitempty" yaml:"type,omitempty"` +} + type LocalKafkaCatalog struct { ApiVersion string `json:"apiVersion" yaml:"apiVersion"` Kind string `json:"kind" yaml:"kind"` diff --git a/test/fixtures/output/flink/application/event-list-help-onprem.golden b/test/fixtures/output/flink/application/event-list-help-onprem.golden deleted file mode 100644 index 6c301ae514..0000000000 --- a/test/fixtures/output/flink/application/event-list-help-onprem.golden +++ /dev/null @@ -1,18 +0,0 @@ -List Flink application events. - -Usage: - confluent flink application event list [flags] - -Flags: - --environment string REQUIRED: Name of the Flink environment. - --application string REQUIRED: Name of the Flink application. - --url string Base URL of the Confluent Manager for Apache Flink (CMF). Environment variable "CONFLUENT_CMF_URL" may be set in place of this flag. - --client-key-path string Path to client private key for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_KEY_PATH" may be set in place of this flag. - --client-cert-path string Path to client cert to be verified by Confluent Manager for Apache Flink. Include for mTLS authentication. Environment variable "CONFLUENT_CMF_CLIENT_CERT_PATH" may be set in place of this flag. - --certificate-authority-path string Path to a PEM-encoded Certificate Authority to verify the Confluent Manager for Apache Flink connection. Environment variable "CONFLUENT_CMF_CERTIFICATE_AUTHORITY_PATH" may be set in place of this flag. - -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") - -Global Flags: - -h, --help Show help for this command. - --unsafe-trace Equivalent to -vvvv, but also log HTTP requests and responses which might contain plaintext secrets. - -v, --verbose count Increase verbosity (-v for warn, -vv for info, -vvv for debug, -vvvv for trace). diff --git a/test/fixtures/output/flink/application/event-list-non-existent-app.golden b/test/fixtures/output/flink/application/event-list-non-existent-app.golden new file mode 100644 index 0000000000..49d5456212 --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-non-existent-app.golden @@ -0,0 +1 @@ +Error: failed to list events for application "non-existent" in the environment "default": Application not found diff --git a/test/fixtures/output/flink/application/event-list-non-existent-env.golden b/test/fixtures/output/flink/application/event-list-non-existent-env.golden new file mode 100644 index 0000000000..c990d26a1e --- /dev/null +++ b/test/fixtures/output/flink/application/event-list-non-existent-env.golden @@ -0,0 +1 @@ +Error: failed to list events for application "some-app" in the environment "non-existent": Environment not found diff --git a/test/flink_onprem_test.go b/test/flink_onprem_test.go index bfd857e9a5..8edf11a7bf 100644 --- a/test/flink_onprem_test.go +++ b/test/flink_onprem_test.go @@ -44,6 +44,8 @@ func (s *CLITestSuite) TestFlinkApplicationEventList() { // failure scenarios {args: "flink application event list", fixture: "flink/application/event-list-missing-flags.golden", exitCode: 1}, {args: "flink application event list --environment default", fixture: "flink/application/event-list-app-missing.golden", exitCode: 1}, + {args: "flink application event list --environment non-existent --application some-app", fixture: "flink/application/event-list-non-existent-env.golden", exitCode: 1}, + {args: "flink application event list --environment default --application non-existent", fixture: "flink/application/event-list-non-existent-app.golden", exitCode: 1}, // success scenarios {args: "flink application event list --environment test --application non-existent", fixture: "flink/application/event-list-empty.golden"}, {args: "flink application event list --environment default --application default-application-1 --output human", fixture: "flink/application/event-list-human.golden"}, diff --git a/test/test-server/flink_onprem_handler.go b/test/test-server/flink_onprem_handler.go index 4183cf760f..0bf34539fb 100644 --- a/test/test-server/flink_onprem_handler.go +++ b/test/test-server/flink_onprem_handler.go @@ -464,6 +464,17 @@ func handleCmfApplicationEvents(t *testing.T) http.HandlerFunc { return } + // Validate application exists, matching handleCmfApplication behavior. + validApps := map[string]bool{ + "default-application-1": true, + "default-application-2": true, + "default-application-s": true, + } + if envName == "default" && !validApps[appName] { + http.Error(w, "Application not found", http.StatusNotFound) + return + } + eventsPage := map[string]interface{}{ "items": []cmfsdk.FlinkApplicationEvent{}, }