diff --git a/internal/cli/log_streams.go b/internal/cli/log_streams.go index 3a86f16c0..f814c22f6 100644 --- a/internal/cli/log_streams.go +++ b/internal/cli/log_streams.go @@ -289,9 +289,20 @@ func (c *cli) logStreamPickerOptionsByType(desiredType logStreamType) pickerOpti } } if len(options) == 0 { - return nil, fmt.Errorf("there are currently no log streams of type: %s", desiredType) + return nil, fmt.Errorf( + "there are currently no log streams of type: %q, use 'auth0 logs streams create %s' to create one", + desiredType, + desiredType, + ) } return options, nil } } + +func errInvalidLogStreamType(id, actual, expected string) error { + message := "the log stream with ID %q is of type %q instead of %q, " + + "use 'auth0 logs streams update %s' to update it instead" + + return fmt.Errorf(message, id, actual, expected, actual) +} diff --git a/internal/cli/log_streams_datadog.go b/internal/cli/log_streams_datadog.go index d52461550..8166bd7e6 100644 --- a/internal/cli/log_streams_datadog.go +++ b/internal/cli/log_streams_datadog.go @@ -132,6 +132,10 @@ func updateLogStreamsDatadogCmd(cli *cli) *cobra.Command { return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) } + if oldLogStream.GetType() != string(logStreamTypeDatadog) { + return errInvalidLogStreamType(inputs.ID, oldLogStream.GetType(), string(logStreamTypeDatadog)) + } + if err := logStreamName.AskU(cmd, &inputs.Name, oldLogStream.Name); err != nil { return err } diff --git a/internal/cli/log_streams_event_bridge.go b/internal/cli/log_streams_event_bridge.go index 7c2b11683..e8e9e74c8 100644 --- a/internal/cli/log_streams_event_bridge.go +++ b/internal/cli/log_streams_event_bridge.go @@ -97,7 +97,7 @@ func updateLogStreamsAmazonEventBridgeCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "eventbridge", - Args: cobra.NoArgs, + Args: cobra.MaximumNArgs(1), Short: "Update an existing Amazon Event Bridge log stream", Long: "Stream real-time Auth0 data to over 15 targets like AWS Lambda.\n\n" + "To update interactively, use `auth0 logs streams create eventbridge` with no arguments.\n\n" + @@ -124,6 +124,10 @@ func updateLogStreamsAmazonEventBridgeCmd(cli *cli) *cobra.Command { return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) } + if oldLogStream.GetType() != string(logStreamTypeAmazonEventBridge) { + return errInvalidLogStreamType(inputs.ID, oldLogStream.GetType(), string(logStreamTypeAmazonEventBridge)) + } + if err := logStreamName.AskU(cmd, &inputs.Name, oldLogStream.Name); err != nil { return err } diff --git a/internal/cli/log_streams_event_grid.go b/internal/cli/log_streams_event_grid.go index b429daa29..fd1dcad13 100644 --- a/internal/cli/log_streams_event_grid.go +++ b/internal/cli/log_streams_event_grid.go @@ -139,6 +139,10 @@ func updateLogStreamsAzureEventGridCmd(cli *cli) *cobra.Command { return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) } + if oldLogStream.GetType() != string(logStreamTypeAzureEventGrid) { + return errInvalidLogStreamType(inputs.ID, oldLogStream.GetType(), string(logStreamTypeAzureEventGrid)) + } + if err := logStreamName.AskU(cmd, &inputs.Name, oldLogStream.Name); err != nil { return err } diff --git a/internal/cli/log_streams_http.go b/internal/cli/log_streams_http.go index 428ee0566..501912234 100644 --- a/internal/cli/log_streams_http.go +++ b/internal/cli/log_streams_http.go @@ -142,7 +142,7 @@ func updateLogStreamsCustomWebhookCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "http", - Args: cobra.NoArgs, + Args: cobra.MaximumNArgs(1), Short: "Update an existing Custom Webhook log stream", Long: "Specify a URL you'd like Auth0 to post events to.\n\n" + "To update interactively, use `auth0 logs streams create http` with no arguments.\n\n" + @@ -173,6 +173,10 @@ func updateLogStreamsCustomWebhookCmd(cli *cli) *cobra.Command { return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) } + if oldLogStream.GetType() != string(logStreamTypeHTTP) { + return errInvalidLogStreamType(inputs.ID, oldLogStream.GetType(), string(logStreamTypeHTTP)) + } + if err := logStreamName.AskU(cmd, &inputs.Name, oldLogStream.Name); err != nil { return err } diff --git a/internal/cli/log_streams_splunk.go b/internal/cli/log_streams_splunk.go index 67b9e9fb4..d120a02e9 100644 --- a/internal/cli/log_streams_splunk.go +++ b/internal/cli/log_streams_splunk.go @@ -132,7 +132,7 @@ func updateLogStreamsSplunkCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "splunk", - Args: cobra.NoArgs, + Args: cobra.MaximumNArgs(1), Short: "Update an existing Splunk log stream", Long: "Monitor real-time logs and display log analytics.\n\n" + "To update interactively, use `auth0 logs streams create splunk` with no arguments.\n\n" + @@ -163,6 +163,10 @@ func updateLogStreamsSplunkCmd(cli *cli) *cobra.Command { return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) } + if oldLogStream.GetType() != string(logStreamTypeSplunk) { + return errInvalidLogStreamType(inputs.ID, oldLogStream.GetType(), string(logStreamTypeSplunk)) + } + if err := logStreamName.AskU(cmd, &inputs.Name, oldLogStream.Name); err != nil { return err } diff --git a/internal/cli/log_streams_sumo.go b/internal/cli/log_streams_sumo.go index a5bbf9e6d..9e768ebe8 100644 --- a/internal/cli/log_streams_sumo.go +++ b/internal/cli/log_streams_sumo.go @@ -83,7 +83,7 @@ func updateLogStreamsSumoLogicCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "sumo", - Args: cobra.NoArgs, + Args: cobra.MaximumNArgs(1), Short: "Update an existing Sumo Logic log stream", Long: "Visualize logs and detect threats faster with security insights.\n\n" + "To update interactively, use `auth0 logs streams create sumo` with no arguments.\n\n" + @@ -111,6 +111,10 @@ func updateLogStreamsSumoLogicCmd(cli *cli) *cobra.Command { return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) } + if oldLogStream.GetType() != string(logStreamTypeSumo) { + return errInvalidLogStreamType(inputs.ID, oldLogStream.GetType(), string(logStreamTypeSumo)) + } + if err := logStreamName.AskU(cmd, &inputs.Name, oldLogStream.Name); err != nil { return err } diff --git a/test/integration/logs-test-cases.yaml b/test/integration/logs-test-cases.yaml new file mode 100644 index 000000000..37668f917 --- /dev/null +++ b/test/integration/logs-test-cases.yaml @@ -0,0 +1,139 @@ +config: + inherit-env: true + +tests: + 001 - it successfully lists all logs: + command: auth0 logs list + exit-code: 0 + stdout: + contains: + - TYPE + - DESCRIPTION + - DATE + - CONNECTION + - CLIENT + + 002 - it successfully lists all log streams: + command: auth0 logs streams list + exit-code: 0 + + 003 - it successfully creates a datadog log stream: + command: ./test/integration/scripts/create-log-stream-datadog-id.sh + exit-code: 0 + + 004 - given a datadog log stream, it successfully gets the log stream's details: + command: auth0 logs streams show $(cat ./test/integration/identifiers/log-stream-datadog-id) + exit-code: 0 + stdout: + contains: + - NAME integration-test-datadog + - TYPE datadog + - STATUS active + + 005 - given a datadog log stream, it successfully gets the log stream's details and outputs in json: + command: auth0 logs streams show $(cat ./test/integration/identifiers/log-stream-datadog-id) --json + exit-code: 0 + stdout: + json: + name: "integration-test-datadog" + type: "datadog" + status: "active" + sink.datadogRegion: "eu" + + 006 - given a datadog log stream, it successfully updates the log stream's details: + command: auth0 logs streams update datadog $(cat ./test/integration/identifiers/log-stream-datadog-id) --name integration-test-updated-datadog --region us --api-key 123123123123123 --json + exit-code: 0 + stdout: + json: + name: "integration-test-updated-datadog" + type: "datadog" + status: "active" + sink.datadogRegion: "us" + + 007 - given a datadog log stream, it successfully opens the log stream's settings page: + command: auth0 logs streams open $(cat ./test/integration/identifiers/log-stream-datadog-id) --no-input + exit-code: 0 + stderr: + contains: + - "Open the following URL in a browser" + + 008 - given a datadog log stream, it successfully deletes the log stream: + command: auth0 logs streams delete $(cat ./test/integration/identifiers/log-stream-datadog-id) --force --no-input + exit-code: 0 + + 009 - it successfully creates an eventbridge log stream: + command: ./test/integration/scripts/create-log-stream-eventbridge-id.sh + exit-code: 0 + + 010 - given an eventbridge log stream, it successfully updates the log stream's details: + command: auth0 logs streams update eventbridge $(cat ./test/integration/identifiers/log-stream-eventbridge-id) --name integration-test-updated-eventbridge --json + exit-code: 0 + stdout: + json: + name: "integration-test-updated-eventbridge" + type: "eventbridge" + status: "active" + + 011 - given an eventbridge log stream, it successfully deletes the log stream: + command: auth0 logs streams delete $(cat ./test/integration/identifiers/log-stream-eventbridge-id) --force --no-input + exit-code: 0 + + 012 - it successfully creates an http log stream: + command: ./test/integration/scripts/create-log-stream-http-id.sh + exit-code: 0 + + 013 - given an http log stream, it successfully updates the log stream's details: + command: auth0 logs streams update http $(cat ./test/integration/identifiers/log-stream-http-id) --name integration-test-updated-http --endpoint "https://example.com/webhook/logs/v2" --format "JSONOBJECT" --json --no-input + exit-code: 0 + stdout: + json: + name: "integration-test-updated-http" + type: "http" + status: "active" + sink.httpContentFormat: "JSONOBJECT" + sink.httpContentType: "application/json" + sink.httpEndpoint: "https://example.com/webhook/logs/v2" + + + 014 - given an http log stream, it successfully deletes the log stream: + command: auth0 logs streams delete $(cat ./test/integration/identifiers/log-stream-http-id) --force --no-input + exit-code: 0 + + 015 - it successfully creates a splunk log stream: + command: ./test/integration/scripts/create-log-stream-splunk-id.sh + exit-code: 0 + + 016 - given a splunk log stream, it successfully updates the log stream's details: + command: auth0 logs streams update splunk $(cat ./test/integration/identifiers/log-stream-splunk-id) --name integration-test-updated-splunk --domain "example.splunk.com" --token "92a34ab5-c6d7-8901-23ef-456b7c89d0c1" --port 8000 --secure --json --no-input + exit-code: 0 + stdout: + json: + name: "integration-test-updated-splunk" + type: "splunk" + status: "active" + sink.splunkDomain: "example.splunk.com" + sink.splunkToken: "92a34ab5-c6d7-8901-23ef-456b7c89d0c1" + sink.splunkPort: "8000" + sink.splunkSecure: "true" + + 017 - given a splunk log stream, it successfully deletes the log stream: + command: auth0 logs streams delete $(cat ./test/integration/identifiers/log-stream-splunk-id) --force --no-input + exit-code: 0 + + 018 - it successfully creates a sumo log stream: + command: ./test/integration/scripts/create-log-stream-sumo-id.sh + exit-code: 0 + + 019 - given a sumo log stream, it successfully updates the log stream's details: + command: auth0 logs streams update sumo $(cat ./test/integration/identifiers/log-stream-sumo-id) --name integration-test-updated-sumo --source "example.sumo.com" --json --no-input + exit-code: 0 + stdout: + json: + name: "integration-test-updated-sumo" + type: "sumo" + status: "active" + sink.sumoSourceAddress: "example.sumo.com" + + 020 - given a sumo log stream, it successfully deletes the log stream: + command: auth0 logs streams delete $(cat ./test/integration/identifiers/log-stream-sumo-id) --force --no-input + exit-code: 0 diff --git a/test/integration/scripts/create-log-stream-datadog-id.sh b/test/integration/scripts/create-log-stream-datadog-id.sh new file mode 100755 index 000000000..b5f2914a8 --- /dev/null +++ b/test/integration/scripts/create-log-stream-datadog-id.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +logStream=$( auth0 logs streams create datadog --name integration-test-datadog --region eu --api-key 123233123455 --json --no-input ) + +mkdir -p ./test/integration/identifiers +echo "$logStream" | jq -r '.["id"]' > ./test/integration/identifiers/log-stream-datadog-id diff --git a/test/integration/scripts/create-log-stream-eventbridge-id.sh b/test/integration/scripts/create-log-stream-eventbridge-id.sh new file mode 100755 index 000000000..fb2ab42b3 --- /dev/null +++ b/test/integration/scripts/create-log-stream-eventbridge-id.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +logStream=$( auth0 logs streams create eventbridge --name integration-test-eventbridge --aws-id 999999999999 --aws-region eu-west-1 --json --no-input ) + +mkdir -p ./test/integration/identifiers +echo "$logStream" | jq -r '.["id"]' > ./test/integration/identifiers/log-stream-eventbridge-id diff --git a/test/integration/scripts/create-log-stream-http-id.sh b/test/integration/scripts/create-log-stream-http-id.sh new file mode 100755 index 000000000..1e195ba8a --- /dev/null +++ b/test/integration/scripts/create-log-stream-http-id.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +logStream=$( auth0 logs streams create http --name integration-test-http --endpoint "https://example.com/webhook/logs" --type "application/json" --format "JSONLINES" --json --no-input ) + +mkdir -p ./test/integration/identifiers +echo "$logStream" | jq -r '.["id"]' > ./test/integration/identifiers/log-stream-http-id diff --git a/test/integration/scripts/create-log-stream-splunk-id.sh b/test/integration/scripts/create-log-stream-splunk-id.sh new file mode 100755 index 000000000..485a9f6be --- /dev/null +++ b/test/integration/scripts/create-log-stream-splunk-id.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +logStream=$( auth0 logs streams create splunk --name integration-test-splunk --domain "demo.splunk.com" --token "12a34ab5-c6d7-8901-23ef-456b7c89d0c1" --port "8088" --secure --json --no-input ) + +mkdir -p ./test/integration/identifiers +echo "$logStream" | jq -r '.["id"]' > ./test/integration/identifiers/log-stream-splunk-id diff --git a/test/integration/scripts/create-log-stream-sumo-id.sh b/test/integration/scripts/create-log-stream-sumo-id.sh new file mode 100755 index 000000000..21641c842 --- /dev/null +++ b/test/integration/scripts/create-log-stream-sumo-id.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +logStream=$( auth0 logs streams create sumo --name integration-test-sumo --source "demo.sumo.com" --json --no-input ) + +mkdir -p ./test/integration/identifiers +echo "$logStream" | jq -r '.["id"]' > ./test/integration/identifiers/log-stream-sumo-id diff --git a/test/integration/test-cases.yaml b/test/integration/test-cases.yaml index cbf712314..a38192e82 100644 --- a/test/integration/test-cases.yaml +++ b/test/integration/test-cases.yaml @@ -5,19 +5,6 @@ tests: auth0 apis list: exit-code: 0 - auth0 logs list: - exit-code: 0 - stdout: - contains: - - TYPE - - DESCRIPTION - - DATE - - CONNECTION - - CLIENT - - auth0 logs streams list: - exit-code: 0 - auth0 tenants list: exit-code: 0