diff --git a/internal/connect/command_artifact_create.go b/internal/connect/command_artifact_create.go index 34a3d0100a..783c57d425 100644 --- a/internal/connect/command_artifact_create.go +++ b/internal/connect/command_artifact_create.go @@ -34,7 +34,7 @@ func (c *artifactCommand) newCreateCommand() *cobra.Command { } cmd.Flags().String("artifact-file", "", "Connect artifact JAR file or ZIP file.") - pcmd.AddCloudAwsFlag(cmd) + pcmd.AddCloudAwsAzureFlag(cmd) pcmd.AddEnvironmentFlag(cmd, c.AuthenticatedCLICommand) cmd.Flags().String("description", "", "Specify the Connect artifact description.") pcmd.AddContextFlag(cmd, c.CLICommand) @@ -80,8 +80,9 @@ func (c *artifactCommand) createArtifact(cmd *cobra.Command, args []string) erro Environment: camv1.PtrString(environment), } - if strings.ToLower(cloud) != "aws" { - return fmt.Errorf("only cloud supported is `AWS`") + supportedClouds := []string{"aws", "azure"} + if !slices.Contains(supportedClouds, strings.ToLower(cloud)) { + return fmt.Errorf("only clouds supported are `AWS` and `AZURE`") } resp, err := c.V2Client.GetArtifactPresignedUrl(request) @@ -89,8 +90,14 @@ func (c *artifactCommand) createArtifact(cmd *cobra.Command, args []string) erro return err } - if err := utils.UploadFile(resp.GetUploadUrl(), artifactFile, resp.GetUploadFormData()); err != nil { - return err + if strings.ToLower(cloud) == "azure" { + if err := utils.UploadFileToAzureBlob(resp.GetUploadUrl(), artifactFile, strings.ToLower(resp.GetContentFormat())); err != nil { + return err + } + } else { + if err := utils.UploadFile(resp.GetUploadUrl(), artifactFile, resp.GetUploadFormData()); err != nil { + return err + } } createArtifactRequest := camv1.CamV1ConnectArtifact{ diff --git a/internal/connect/command_artifact_delete.go b/internal/connect/command_artifact_delete.go index 65a368e900..5b3bbba7fe 100644 --- a/internal/connect/command_artifact_delete.go +++ b/internal/connect/command_artifact_delete.go @@ -25,7 +25,7 @@ func (c *artifactCommand) newDeleteCommand() *cobra.Command { ), } - pcmd.AddCloudAwsFlag(cmd) + pcmd.AddCloudAwsAzureFlag(cmd) pcmd.AddEnvironmentFlag(cmd, c.AuthenticatedCLICommand) pcmd.AddContextFlag(cmd, c.CLICommand) pcmd.AddForceFlag(cmd) diff --git a/internal/connect/command_artifact_describe.go b/internal/connect/command_artifact_describe.go index bf35db7cba..527683502c 100644 --- a/internal/connect/command_artifact_describe.go +++ b/internal/connect/command_artifact_describe.go @@ -23,7 +23,7 @@ func (c *artifactCommand) newDescribeCommand() *cobra.Command { ), } - pcmd.AddCloudAwsFlag(cmd) + pcmd.AddCloudAwsAzureFlag(cmd) pcmd.AddEnvironmentFlag(cmd, c.AuthenticatedCLICommand) pcmd.AddContextFlag(cmd, c.CLICommand) pcmd.AddOutputFlag(cmd) diff --git a/internal/connect/command_artifact_list.go b/internal/connect/command_artifact_list.go index 51648c969b..b40b520ec2 100644 --- a/internal/connect/command_artifact_list.go +++ b/internal/connect/command_artifact_list.go @@ -24,7 +24,7 @@ func (c *artifactCommand) newListCommand() *cobra.Command { ), } - pcmd.AddCloudAwsFlag(cmd) + pcmd.AddCloudAwsAzureFlag(cmd) pcmd.AddEnvironmentFlag(cmd, c.AuthenticatedCLICommand) pcmd.AddContextFlag(cmd, c.CLICommand) pcmd.AddOutputFlag(cmd) diff --git a/test/connect_test.go b/test/connect_test.go index 96944b902a..a52146b6fc 100644 --- a/test/connect_test.go +++ b/test/connect_test.go @@ -51,7 +51,7 @@ func (s *CLITestSuite) TestConnectArtifact() { tests := []CLITest{ {args: `connect artifact create my-connect-artifact-jar --artifact-file "test/fixtures/input/connect/artifact-example.jar" --cloud aws --environment env-123456 --description new-jar-artifact`, fixture: "connect/artifact/create-jar.golden"}, {args: `connect artifact create my-connect-artifact-zip --artifact-file "test/fixtures/input/connect/artifact-example.zip" --cloud aws --environment env-123456 --description new-zip-artifact`, fixture: "connect/artifact/create-zip.golden"}, - {args: `connect artifact create my-connect-artifact --artifact-file "test/fixtures/input/connect/artifact-example.zip" --cloud azure --environment env-123456 --description new-invalid-artifact`, fixture: "connect/artifact/create-invalid-cloud-type.golden", exitCode: 1}, + {args: `connect artifact create my-connect-artifact --artifact-file "test/fixtures/input/connect/artifact-example.zip" --cloud gcp --environment env-123456 --description new-invalid-artifact`, fixture: "connect/artifact/create-invalid-cloud-type.golden", exitCode: 1}, {args: `connect artifact create my-connect-artifact --artifact-file "test/fixtures/input/connect/artifact-example.jpg" --cloud aws --environment env-123456 --description new-invalid-artifact`, fixture: "connect/artifact/create-invalid-file-type.golden", exitCode: 1}, {args: "connect artifact list --cloud aws --environment env-123456", fixture: "connect/artifact/list.golden"}, {args: "connect artifact list --cloud aws --environment env-123456 -o json", fixture: "connect/artifact/list-json.golden"}, @@ -63,6 +63,19 @@ func (s *CLITestSuite) TestConnectArtifact() { {args: "connect artifact delete cfa-zip123 --cloud aws --environment env-123456 --force", fixture: "connect/artifact/delete-force.golden"}, {args: "connect artifact delete cfa-zip123 --cloud aws --environment env-123456", input: "y\n", fixture: "connect/artifact/delete-prompt.golden"}, {args: "connect artifact delete cfa-invalid --cloud aws --environment env-123456", fixture: "connect/artifact/delete-invalid-artifact.golden", exitCode: 1}, + + // Azure tests + {args: `connect artifact create my-connect-artifact-azure-jar --artifact-file "test/fixtures/input/connect/artifact-example.jar" --cloud azure --environment env-123456 --description new-jar-artifact`, fixture: "connect/artifact/create-azure-jar.golden"}, + {args: `connect artifact create my-connect-artifact-azure-zip --artifact-file "test/fixtures/input/connect/artifact-example.zip" --cloud azure --environment env-123456 --description new-zip-artifact`, fixture: "connect/artifact/create-azure-zip.golden"}, + {args: "connect artifact list --cloud azure --environment env-123456", fixture: "connect/artifact/list-azure.golden"}, + {args: "connect artifact list --cloud azure --environment env-123456 -o json", fixture: "connect/artifact/list-azure-json.golden"}, + {args: "connect artifact list --cloud azure --environment env-123456 -o yaml", fixture: "connect/artifact/list-azure-yaml.golden"}, + {args: "connect artifact describe cfa-azure-zip123 --cloud azure --environment env-123456", fixture: "connect/artifact/describe-azure-zip.golden"}, + {args: "connect artifact describe cfa-azure-jar123 --cloud azure --environment env-123456", fixture: "connect/artifact/describe-azure-jar.golden"}, + {args: "connect artifact describe cfa-azure-jar123 --cloud azure --environment env-123456 -o json", fixture: "connect/artifact/describe-azure-json.golden"}, + {args: "connect artifact describe cfa-azure-jar123 --cloud azure --environment env-123456 -o yaml", fixture: "connect/artifact/describe-azure-yaml.golden"}, + {args: "connect artifact delete cfa-azure-zip123 --cloud azure --environment env-123456 --force", fixture: "connect/artifact/delete-azure-force.golden"}, + {args: "connect artifact delete cfa-azure-zip123 --cloud azure --environment env-123456", input: "y\n", fixture: "connect/artifact/delete-azure-prompt.golden"}, } for _, test := range tests { diff --git a/test/fixtures/output/connect/artifact/create-azure-jar.golden b/test/fixtures/output/connect/artifact/create-azure-jar.golden new file mode 100644 index 0000000000..58699c0e2a --- /dev/null +++ b/test/fixtures/output/connect/artifact/create-azure-jar.golden @@ -0,0 +1,9 @@ ++----------------+-------------------------------+ +| ID | cfa-azure-jar123 | +| Name | my-connect-artifact-azure-jar | +| Description | new-jar-artifact | +| Cloud | AZURE | +| Environment | env-123456 | +| Content Format | JAR | +| Status | PROCESSING | ++----------------+-------------------------------+ diff --git a/test/fixtures/output/connect/artifact/create-azure-zip.golden b/test/fixtures/output/connect/artifact/create-azure-zip.golden new file mode 100644 index 0000000000..09f99bc2af --- /dev/null +++ b/test/fixtures/output/connect/artifact/create-azure-zip.golden @@ -0,0 +1,9 @@ ++----------------+-------------------------------+ +| ID | cfa-azure-zip123 | +| Name | my-connect-artifact-azure-zip | +| Description | new-zip-artifact | +| Cloud | AZURE | +| Environment | env-123456 | +| Content Format | ZIP | +| Status | PROCESSING | ++----------------+-------------------------------+ diff --git a/test/fixtures/output/connect/artifact/create-help.golden b/test/fixtures/output/connect/artifact/create-help.golden index cd5e65bc60..5aab740d82 100644 --- a/test/fixtures/output/connect/artifact/create-help.golden +++ b/test/fixtures/output/connect/artifact/create-help.golden @@ -10,7 +10,7 @@ Create Connect artifact "my-connect-artifact". Flags: --artifact-file string REQUIRED: Connect artifact JAR file or ZIP file. - --cloud string REQUIRED: Specify the cloud provider as "aws". + --cloud string REQUIRED: Specify the cloud provider as "aws" or "azure". --environment string Environment ID. --description string Specify the Connect artifact description. --context string CLI context name. diff --git a/test/fixtures/output/connect/artifact/create-invalid-cloud-type.golden b/test/fixtures/output/connect/artifact/create-invalid-cloud-type.golden index 8c73890fed..63261e4e40 100644 --- a/test/fixtures/output/connect/artifact/create-invalid-cloud-type.golden +++ b/test/fixtures/output/connect/artifact/create-invalid-cloud-type.golden @@ -1 +1 @@ -Error: only cloud supported is `AWS` +Error: only clouds supported are `AWS` and `AZURE` diff --git a/test/fixtures/output/connect/artifact/delete-azure-force.golden b/test/fixtures/output/connect/artifact/delete-azure-force.golden new file mode 100644 index 0000000000..f0d6dab10f --- /dev/null +++ b/test/fixtures/output/connect/artifact/delete-azure-force.golden @@ -0,0 +1 @@ +Deleted Connect Artifact "cfa-azure-zip123". diff --git a/test/fixtures/output/connect/artifact/delete-azure-prompt.golden b/test/fixtures/output/connect/artifact/delete-azure-prompt.golden new file mode 100644 index 0000000000..47862e8635 --- /dev/null +++ b/test/fixtures/output/connect/artifact/delete-azure-prompt.golden @@ -0,0 +1 @@ +Are you sure you want to delete Connect Artifact "cfa-azure-zip123"? (y/n): Deleted Connect Artifact "cfa-azure-zip123". diff --git a/test/fixtures/output/connect/artifact/delete-help.golden b/test/fixtures/output/connect/artifact/delete-help.golden index 2b7caecb67..035c3e09e1 100644 --- a/test/fixtures/output/connect/artifact/delete-help.golden +++ b/test/fixtures/output/connect/artifact/delete-help.golden @@ -9,7 +9,7 @@ Delete Connect artifact. $ confluent connect artifact delete cfa-abc123 --cloud aws --environment env-abc123 Flags: - --cloud string REQUIRED: Specify the cloud provider as "aws". + --cloud string REQUIRED: Specify the cloud provider as "aws" or "azure". --environment string Environment ID. --context string CLI context name. --force Skip the deletion confirmation prompt. diff --git a/test/fixtures/output/connect/artifact/describe-azure-jar.golden b/test/fixtures/output/connect/artifact/describe-azure-jar.golden new file mode 100644 index 0000000000..c16ce20ced --- /dev/null +++ b/test/fixtures/output/connect/artifact/describe-azure-jar.golden @@ -0,0 +1,9 @@ ++----------------+-------------------------------+ +| ID | cfa-azure-jar123 | +| Name | my-connect-artifact-azure-jar | +| Description | new-jar-artifact | +| Cloud | AZURE | +| Environment | env-123456 | +| Content Format | JAR | +| Status | READY | ++----------------+-------------------------------+ diff --git a/test/fixtures/output/connect/artifact/describe-azure-json.golden b/test/fixtures/output/connect/artifact/describe-azure-json.golden new file mode 100644 index 0000000000..8629fe7c0a --- /dev/null +++ b/test/fixtures/output/connect/artifact/describe-azure-json.golden @@ -0,0 +1,9 @@ +{ + "id": "cfa-azure-jar123", + "name": "my-connect-artifact-azure-jar", + "description": "new-jar-artifact", + "cloud": "AZURE", + "environment": "env-123456", + "content_format": "JAR", + "status": "READY" +} diff --git a/test/fixtures/output/connect/artifact/describe-azure-yaml.golden b/test/fixtures/output/connect/artifact/describe-azure-yaml.golden new file mode 100644 index 0000000000..68785330a7 --- /dev/null +++ b/test/fixtures/output/connect/artifact/describe-azure-yaml.golden @@ -0,0 +1,7 @@ +id: cfa-azure-jar123 +name: my-connect-artifact-azure-jar +description: new-jar-artifact +cloud: AZURE +environment: env-123456 +content_format: JAR +status: READY diff --git a/test/fixtures/output/connect/artifact/describe-azure-zip.golden b/test/fixtures/output/connect/artifact/describe-azure-zip.golden new file mode 100644 index 0000000000..09f99bc2af --- /dev/null +++ b/test/fixtures/output/connect/artifact/describe-azure-zip.golden @@ -0,0 +1,9 @@ ++----------------+-------------------------------+ +| ID | cfa-azure-zip123 | +| Name | my-connect-artifact-azure-zip | +| Description | new-zip-artifact | +| Cloud | AZURE | +| Environment | env-123456 | +| Content Format | ZIP | +| Status | PROCESSING | ++----------------+-------------------------------+ diff --git a/test/fixtures/output/connect/artifact/describe-help.golden b/test/fixtures/output/connect/artifact/describe-help.golden index 2d93655328..7a85bc92b4 100644 --- a/test/fixtures/output/connect/artifact/describe-help.golden +++ b/test/fixtures/output/connect/artifact/describe-help.golden @@ -9,7 +9,7 @@ Describe a Connect artifact. $ confluent connect artifact describe cfa-abc123 --cloud aws --environment env-abc123 Flags: - --cloud string REQUIRED: Specify the cloud provider as "aws". + --cloud string REQUIRED: Specify the cloud provider as "aws" or "azure". --environment string Environment ID. --context string CLI context name. -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") diff --git a/test/fixtures/output/connect/artifact/list-azure-json.golden b/test/fixtures/output/connect/artifact/list-azure-json.golden new file mode 100644 index 0000000000..39ef2bee6c --- /dev/null +++ b/test/fixtures/output/connect/artifact/list-azure-json.golden @@ -0,0 +1,20 @@ +[ + { + "id": "cfa-azure-jar123", + "name": "my-connect-artifact-azure-jar", + "description": "new-jar-artifact", + "cloud": "AZURE", + "environment": "env-123456", + "content_format": "JAR", + "status": "READY" + }, + { + "id": "cfa-azure-zip123", + "name": "my-connect-artifact-azure-zip", + "description": "new-zip-artifact", + "cloud": "AZURE", + "environment": "env-123456", + "content_format": "ZIP", + "status": "PROCESSING" + } +] diff --git a/test/fixtures/output/connect/artifact/list-azure-yaml.golden b/test/fixtures/output/connect/artifact/list-azure-yaml.golden new file mode 100644 index 0000000000..8a9808ad1d --- /dev/null +++ b/test/fixtures/output/connect/artifact/list-azure-yaml.golden @@ -0,0 +1,14 @@ +- id: cfa-azure-jar123 + name: my-connect-artifact-azure-jar + description: new-jar-artifact + cloud: AZURE + environment: env-123456 + content_format: JAR + status: READY +- id: cfa-azure-zip123 + name: my-connect-artifact-azure-zip + description: new-zip-artifact + cloud: AZURE + environment: env-123456 + content_format: ZIP + status: PROCESSING diff --git a/test/fixtures/output/connect/artifact/list-azure.golden b/test/fixtures/output/connect/artifact/list-azure.golden new file mode 100644 index 0000000000..52388855b7 --- /dev/null +++ b/test/fixtures/output/connect/artifact/list-azure.golden @@ -0,0 +1,4 @@ + ID | Name | Description | Cloud | Environment | Content Format | Status +-------------------+-------------------------------+------------------+-------+-------------+----------------+------------- + cfa-azure-jar123 | my-connect-artifact-azure-jar | new-jar-artifact | AZURE | env-123456 | JAR | READY + cfa-azure-zip123 | my-connect-artifact-azure-zip | new-zip-artifact | AZURE | env-123456 | ZIP | PROCESSING diff --git a/test/fixtures/output/connect/artifact/list-help.golden b/test/fixtures/output/connect/artifact/list-help.golden index 74708e17f0..eb2df9138d 100644 --- a/test/fixtures/output/connect/artifact/list-help.golden +++ b/test/fixtures/output/connect/artifact/list-help.golden @@ -9,7 +9,7 @@ List Connect artifacts. $ confluent connect artifact list --cloud aws --environment env-abc123 Flags: - --cloud string REQUIRED: Specify the cloud provider as "aws". + --cloud string REQUIRED: Specify the cloud provider as "aws" or "azure". --environment string Environment ID. --context string CLI context name. -o, --output string Specify the output format as "human", "json", or "yaml". (default "human") diff --git a/test/test-server/connect_handler.go b/test/test-server/connect_handler.go index ee09a986d0..40962b192a 100644 --- a/test/test-server/connect_handler.go +++ b/test/test-server/connect_handler.go @@ -185,6 +185,12 @@ func handleConnectArtifacts(t *testing.T) http.HandlerFunc { case "my-connect-artifact-zip": artifact.SetId("cfa-zip123") artifact.Spec.SetContentFormat("ZIP") + case "my-connect-artifact-azure-jar": + artifact.SetId("cfa-azure-jar123") + artifact.Spec.SetContentFormat("JAR") + case "my-connect-artifact-azure-zip": + artifact.SetId("cfa-azure-zip123") + artifact.Spec.SetContentFormat("ZIP") } artifact.Status = &camv1.CamV1ConnectArtifactStatus{ @@ -196,9 +202,32 @@ func handleConnectArtifacts(t *testing.T) http.HandlerFunc { err := json.NewEncoder(w).Encode(artifact) require.NoError(t, err) case http.MethodGet: + // Try multiple possible query parameter names - the SDK might use different formats + cloud := "" + queryParams := r.URL.Query() + // Check common variations + for _, param := range []string{"spec.cloud", "cloud", "spec_cloud"} { + if val := queryParams.Get(param); val != "" { + cloud = strings.ToUpper(val) + break + } + } + // Also check all query params in case the name is different + if cloud == "" { + for key, values := range queryParams { + if len(values) > 0 && (strings.Contains(strings.ToLower(key), "cloud") || strings.Contains(strings.ToLower(key), "spec")) { + cloud = strings.ToUpper(values[0]) + break + } + } + } var artifacts []camv1.CamV1ConnectArtifact for _, artifact := range artifactStore { - if artifact.GetId() == "cfa-jar123" { + // Filter by cloud if specified + if cloud != "" && strings.ToUpper(artifact.Spec.GetCloud()) != cloud { + continue + } + if artifact.GetId() == "cfa-jar123" || artifact.GetId() == "cfa-azure-jar123" { artifact.Status = &camv1.CamV1ConnectArtifactStatus{ Phase: "READY", } @@ -227,7 +256,7 @@ func handleConnectArtifactId(t *testing.T) http.HandlerFunc { return } - if id == "cfa-jar123" { + if id == "cfa-jar123" || id == "cfa-azure-jar123" { artifact.Status = &camv1.CamV1ConnectArtifactStatus{ Phase: "READY", } @@ -244,7 +273,7 @@ func handleConnectArtifactId(t *testing.T) http.HandlerFunc { return } - if id == "cfa-zip123" { + if id == "cfa-zip123" || id == "cfa-azure-zip123" { w.WriteHeader(http.StatusNoContent) } } @@ -255,11 +284,21 @@ func handleConnectArtifactId(t *testing.T) http.HandlerFunc { func handleConnectArtifactUploadUrl(t *testing.T) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { + var request camv1.CamV1PresignedUrlRequest + require.NoError(t, json.NewDecoder(r.Body).Decode(&request)) + + cloud := strings.ToUpper(request.GetCloud()) + contentFormat := request.GetContentFormat() + if contentFormat == "" { + contentFormat = "JAR" + } + uploadUrl := camv1.CamV1PresignedUrl{ - Cloud: camv1.PtrString("AWS"), - Environment: camv1.PtrString("env-123456"), - UploadId: camv1.PtrString("e53bb2e8-8de3-49fa-9fb1-4e3fd9a16b66"), - UploadUrl: camv1.PtrString(fmt.Sprintf("%s/cam/v1/dummy-presigned-url", TestV2CloudUrl.String())), + Cloud: camv1.PtrString(cloud), + Environment: camv1.PtrString(request.GetEnvironment()), + UploadId: camv1.PtrString("e53bb2e8-8de3-49fa-9fb1-4e3fd9a16b66"), + UploadUrl: camv1.PtrString(fmt.Sprintf("%s/cam/v1/dummy-presigned-url", TestV2CloudUrl.String())), + ContentFormat: camv1.PtrString(strings.ToUpper(contentFormat)), } err := json.NewEncoder(w).Encode(uploadUrl) require.NoError(t, err) @@ -270,7 +309,7 @@ func handleConnectArtifactUploadUrl(t *testing.T) http.HandlerFunc { // Handler for: "/cam/v1/dummy-presigned-url" func handleConnectArtifactUploadFile(t *testing.T) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodPost { + if r.Method == http.MethodPost || r.Method == http.MethodPut { err := json.NewEncoder(w).Encode(camv1.PtrString("Success")) require.NoError(t, err) }