Repository: innabox/fulfillment-cli
Pull request #5: Add clusterorder delete command
Author: login: tzumainn
Created: 2025-04-09T16:25:40Z | Merged: 2025-04-10T07:17:37Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a CLI command to delete a cluster order by providing its unique identifier.
  - Integrated deletion functionality into the main command interface with clear error and confirmation messages for user feedback.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go b/internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go
new file mode 100644
index 0000000..8bc1e5e
--- /dev/null
+++ b/internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go
@@ -0,0 +1,90 @@
+/*
+Copyright (c) 2025 Red Hat Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+*/
+
+package clusterorder
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/spf13/cobra"
+
+	fulfillmentv1 "github.com/innabox/fulfillment-cli/internal/api/fulfillment/v1"
+	"github.com/innabox/fulfillment-cli/internal/config"
+)
+
+func Cmd() *cobra.Command {
+	runner := &runnerContext{}
+	result := &cobra.Command{
+		Use:     "clusterorder [flags] ID",
+		Aliases: []string{"clusterorders"},
+		Short:   "Delete a cluster order",
+		RunE:    runner.run,
+	}
+	return result
+}
+
+type runnerContext struct {
+}
+
+func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
+        // Check that there is exactly one cluster order ID specified
+        if len(args) != 1 {
+	        fmt.Fprintf(
+                        os.Stderr,
+                        "Expected exactly one cluster order ID\n",
+	        )
+                os.Exit(1)
+        }
+	orderId := args[0]
+
+	// Get the context:
+	ctx := cmd.Context()
+
+	// Get the configuration:
+	cfg, err := config.Load()
+	if err != nil {
+		return err
+	}
+	if cfg.Address == "" {
+		return fmt.Errorf("there is no configuration, run the 'login' command")
+	}
+
+	// Create the gRPC connection from the configuration:
+	conn, err := cfg.Connect()
+	if err != nil {
+		return fmt.Errorf("failed to create gRPC connection: %w", err)
+	}
+
+	// Create the client for the cluster orders service:
+	client := fulfillmentv1.NewClusterOrdersClient(conn)
+
+	// Get the order:
+	_, err = client.Get(ctx, &fulfillmentv1.ClusterOrdersGetRequest{
+		Id: orderId,
+	})
+	if err != nil {
+		return fmt.Errorf("failed to retrieve order: %w", err)
+	}
+
+	// Delete the order:
+	_, err = client.Delete(ctx, &fulfillmentv1.ClusterOrdersDeleteRequest{
+		Id: orderId,
+	})
+	if err != nil {
+		return fmt.Errorf("failed to delete order: %w", err)
+	}
+	fmt.Printf("Deleted cluster order '%s''\n", orderId)
+
+	return nil
+}
diff --git a/internal/cmd/delete/delete_cmd.go b/internal/cmd/delete/delete_cmd.go
new file mode 100644
index 0000000..b48a6c4
--- /dev/null
+++ b/internal/cmd/delete/delete_cmd.go
@@ -0,0 +1,29 @@
+/*
+Copyright (c) 2025 Red Hat Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+*/
+
+package delete
+
+import (
+	"github.com/spf13/cobra"
+
+	"github.com/innabox/fulfillment-cli/internal/cmd/delete/clusterorder"
+)
+
+func Cmd() *cobra.Command {
+	result := &cobra.Command{
+		Use:   "delete",
+		Short: "Delete resource",
+	}
+	result.AddCommand(clusterorder.Cmd())
+	return result
+}
diff --git a/internal/cmd/root_cmd.go b/internal/cmd/root_cmd.go
index c14af84..399c6ba 100644
--- a/internal/cmd/root_cmd.go
+++ b/internal/cmd/root_cmd.go
@@ -17,6 +17,7 @@ import (
 	"github.com/spf13/cobra"
 
 	"github.com/innabox/fulfillment-cli/internal/cmd/create"
+	"github.com/innabox/fulfillment-cli/internal/cmd/delete"
 	"github.com/innabox/fulfillment-cli/internal/cmd/describe"
 	"github.com/innabox/fulfillment-cli/internal/cmd/get"
 	"github.com/innabox/fulfillment-cli/internal/cmd/getkubeconfig"
@@ -32,6 +33,7 @@ func Root() *cobra.Command {
 		SilenceErrors: true,
 	}
 	result.AddCommand(create.Cmd())
+	result.AddCommand(delete.Cmd())
 	result.AddCommand(describe.Cmd())
 	result.AddCommand(get.Cmd())
 	result.AddCommand(getkubeconfig.Cmd())


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go (2)</summary><blockquote>

`63-68`: **Add deferred connection close.**

The gRPC connection is established but never explicitly closed. Add a deferred close statement to ensure proper resource cleanup.


```diff
// Create the gRPC connection from the configuration:
conn, err := cfg.Connect()
if err != nil {
	return fmt.Errorf("failed to create gRPC connection: %w", err)
}
+defer conn.Close()
```

---

`87-87`: **Fix typo in success message.**

There's an extra apostrophe in the success message.


```diff
-fmt.Printf("Deleted cluster order '%s''\n", orderId)
+fmt.Printf("Deleted cluster order '%s'\n", orderId)
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between e918e87059ae25c5082290a3b054fcca038c086e and 2fb2603c5909661310ca6c81ea8e0c9b59b3754d.

</details>

<details>
<summary>📒 Files selected for processing (3)</summary>

* `internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go` (1 hunks)
* `internal/cmd/delete/delete_cmd.go` (1 hunks)
* `internal/cmd/root_cmd.go` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (3)</summary>

<details>
<summary>internal/cmd/root_cmd.go (2)</summary><blockquote>

<details>
<summary>internal/cmd/delete/delete_cmd.go (1)</summary>

* `Cmd` (22-29)

</details>
<details>
<summary>internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go (1)</summary>

* `Cmd` (26-35)

</details>

</blockquote></details>
<details>
<summary>internal/cmd/delete/delete_cmd.go (1)</summary><blockquote>

<details>
<summary>internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go (1)</summary>

* `Cmd` (26-35)

</details>

</blockquote></details>
<details>
<summary>internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go (3)</summary><blockquote>

<details>
<summary>internal/cmd/delete/delete_cmd.go (1)</summary>

* `Cmd` (22-29)

</details>
<details>
<summary>internal/config/config.go (1)</summary>

* `Load` (41-71)

</details>
<details>
<summary>internal/api/fulfillment/v1/cluster_orders_service_grpc.pb.go (1)</summary>

* `NewClusterOrdersClient` (84-86)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (5)</summary><blockquote>

<details>
<summary>internal/cmd/delete/delete_cmd.go (1)</summary>

`22-29`: **LGTM! The delete command structure is well-organized.**

The implementation follows the command pattern used by other commands in the application, creating a parent "delete" command that can house multiple resource deletion subcommands.

</details>
<details>
<summary>internal/cmd/root_cmd.go (2)</summary>

`19-21`: **LGTM! Import added correctly.**

The delete package is properly imported.

---

`36-36`: **LGTM! Command integration is correct.**

The delete command is properly integrated into the root command structure, following the same pattern as other commands.

</details>
<details>
<summary>internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go (2)</summary>

`26-35`: **LGTM! Command setup is well structured.**

The command is properly defined with appropriate usage instructions, aliases, and description.

---

`72-78`: **LGTM! Order existence check before deletion.**

Good practice to verify the order exists before attempting to delete it.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-09T16:28:14Z
user: login: jhernand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T18:09:26Z
user: login: tzumainn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T18:37:58Z
user: login: jhernand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T07:17:13Z
user: login: jhernand
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-10T07:17:30Z

Review comments:
diff_hunk: @@ -0,0 +1,90 @@
+/*
+Copyright (c) 2025 Red Hat Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+*/
+
+package clusterorder
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/spf13/cobra"
+
+	fulfillmentv1 "github.com/innabox/fulfillment-cli/internal/api/fulfillment/v1"
+	"github.com/innabox/fulfillment-cli/internal/config"
+)
+
+func Cmd() *cobra.Command {
+	runner := &runnerContext{}
+	result := &cobra.Command{
+		Use:     "clusterorder [flags] ID",
+		Aliases: []string{"clusterorders"},
+		Short:   "Delete a cluster order",
+		RunE:    runner.run,
+	}
+	return result
+}
+
+type runnerContext struct {
+}
+
+func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
+        // Check that there is exactly one cluster order ID specified
+        if len(args) != 1 {
+	        fmt.Fprintf(
+                        os.Stderr,
+                        "Expected exactly one cluster order ID\n",
+	        )
+                os.Exit(1)
+        }
path: internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Use error return instead of direct exit.**

Directly calling `os.Exit(1)` bypasses Cobra's error handling mechanism. Instead, return an error to let Cobra handle it properly.


```diff
if len(args) != 1 {
-	fmt.Fprintf(
-		os.Stderr,
-		"Expected exactly one cluster order ID\n",
-	)
-	os.Exit(1)
+	return fmt.Errorf("expected exactly one cluster order ID")
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
        // Check that there is exactly one cluster order ID specified
        if len(args) != 1 {
            return fmt.Errorf("expected exactly one cluster order ID")
        }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-09T16:28:13Z
author_association: NONE
diff_hunk: @@ -0,0 +1,90 @@
+/*
+Copyright (c) 2025 Red Hat Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+*/
+
+package clusterorder
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/spf13/cobra"
+
+	fulfillmentv1 "github.com/innabox/fulfillment-cli/internal/api/fulfillment/v1"
+	"github.com/innabox/fulfillment-cli/internal/config"
+)
+
+func Cmd() *cobra.Command {
+	runner := &runnerContext{}
+	result := &cobra.Command{
+		Use:     "clusterorder [flags] ID",
+		Aliases: []string{"clusterorders"},
+		Short:   "Delete a cluster order",
+		RunE:    runner.run,
+	}
+	return result
+}
+
+type runnerContext struct {
+}
+
+func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
+        // Check that there is exactly one cluster order ID specified
+        if len(args) != 1 {
+	        fmt.Fprintf(
+                        os.Stderr,
+                        "Expected exactly one cluster order ID\n",
+	        )
+                os.Exit(1)
+        }
+	orderId := args[0]
+
+	// Get the context:
+	ctx := cmd.Context()
+
+	// Get the configuration:
+	cfg, err := config.Load()
+	if err != nil {
+		return err
+	}
+	if cfg.Address == "" {
+		return fmt.Errorf("there is no configuration, run the 'login' command")
+	}
+
+	// Create the gRPC connection from the configuration:
+	conn, err := cfg.Connect()
+	if err != nil {
+		return fmt.Errorf("failed to create gRPC connection: %w", err)
+	}
+
+	// Create the client for the cluster orders service:
+	client := fulfillmentv1.NewClusterOrdersClient(conn)
+
+	// Get the order:
+	_, err = client.Get(ctx, &fulfillmentv1.ClusterOrdersGetRequest{
+		Id: orderId,
+	})
+	if err != nil {
+		return fmt.Errorf("failed to retrieve order: %w", err)
+	}
path: internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go
user: login: jhernand
body: I'd say that it isn't necessary to retrieve the object first: the `Delete` method below should return an error if the object doesn't exist. If it doesn't then that is a bug in the server.
created_at: 2025-04-09T18:09:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,90 @@
+/*
+Copyright (c) 2025 Red Hat Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+*/
+
+package clusterorder
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/spf13/cobra"
+
+	fulfillmentv1 "github.com/innabox/fulfillment-cli/internal/api/fulfillment/v1"
+	"github.com/innabox/fulfillment-cli/internal/config"
+)
+
+func Cmd() *cobra.Command {
+	runner := &runnerContext{}
+	result := &cobra.Command{
+		Use:     "clusterorder [flags] ID",
+		Aliases: []string{"clusterorders"},
+		Short:   "Delete a cluster order",
+		RunE:    runner.run,
+	}
+	return result
+}
+
+type runnerContext struct {
+}
+
+func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
+        // Check that there is exactly one cluster order ID specified
+        if len(args) != 1 {
+	        fmt.Fprintf(
+                        os.Stderr,
+                        "Expected exactly one cluster order ID\n",
+	        )
+                os.Exit(1)
+        }
+	orderId := args[0]
+
+	// Get the context:
+	ctx := cmd.Context()
+
+	// Get the configuration:
+	cfg, err := config.Load()
+	if err != nil {
+		return err
+	}
+	if cfg.Address == "" {
+		return fmt.Errorf("there is no configuration, run the 'login' command")
+	}
+
+	// Create the gRPC connection from the configuration:
+	conn, err := cfg.Connect()
+	if err != nil {
+		return fmt.Errorf("failed to create gRPC connection: %w", err)
+	}
+
+	// Create the client for the cluster orders service:
+	client := fulfillmentv1.NewClusterOrdersClient(conn)
+
+	// Get the order:
+	_, err = client.Get(ctx, &fulfillmentv1.ClusterOrdersGetRequest{
+		Id: orderId,
+	})
+	if err != nil {
+		return fmt.Errorf("failed to retrieve order: %w", err)
+	}
path: internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go
user: login: tzumainn
body: It does return an error, just one that I thought might be a bit deceptive, as it implies that the object may exist:

```
$ ./fulfillment-cli delete clusterorder foo
Error: failed to delete order: rpc error: code = Internal desc = failed to delete object
```

But I can remove this check if you think the server should return a different error if the object doesn't exist?
created_at: 2025-04-09T18:37:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,90 @@
+/*
+Copyright (c) 2025 Red Hat Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+language governing permissions and limitations under the License.
+*/
+
+package clusterorder
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/spf13/cobra"
+
+	fulfillmentv1 "github.com/innabox/fulfillment-cli/internal/api/fulfillment/v1"
+	"github.com/innabox/fulfillment-cli/internal/config"
+)
+
+func Cmd() *cobra.Command {
+	runner := &runnerContext{}
+	result := &cobra.Command{
+		Use:     "clusterorder [flags] ID",
+		Aliases: []string{"clusterorders"},
+		Short:   "Delete a cluster order",
+		RunE:    runner.run,
+	}
+	return result
+}
+
+type runnerContext struct {
+}
+
+func (c *runnerContext) run(cmd *cobra.Command, args []string) error {
+        // Check that there is exactly one cluster order ID specified
+        if len(args) != 1 {
+	        fmt.Fprintf(
+                        os.Stderr,
+                        "Expected exactly one cluster order ID\n",
+	        )
+                os.Exit(1)
+        }
+	orderId := args[0]
+
+	// Get the context:
+	ctx := cmd.Context()
+
+	// Get the configuration:
+	cfg, err := config.Load()
+	if err != nil {
+		return err
+	}
+	if cfg.Address == "" {
+		return fmt.Errorf("there is no configuration, run the 'login' command")
+	}
+
+	// Create the gRPC connection from the configuration:
+	conn, err := cfg.Connect()
+	if err != nil {
+		return fmt.Errorf("failed to create gRPC connection: %w", err)
+	}
+
+	// Create the client for the cluster orders service:
+	client := fulfillmentv1.NewClusterOrdersClient(conn)
+
+	// Get the order:
+	_, err = client.Get(ctx, &fulfillmentv1.ClusterOrdersGetRequest{
+		Id: orderId,
+	})
+	if err != nil {
+		return fmt.Errorf("failed to retrieve order: %w", err)
+	}
path: internal/cmd/delete/clusterorder/delete_clusterorder_cmd.go
user: login: jhernand
body: I see, I'd say that is a bug in the server. Lets merge this as is and we change it when the server is fixed.
created_at: 2025-04-10T07:17:13Z
author_association: CONTRIBUTOR

PR comments:
user: login: tzumainn
created_at: 2025-04-09T16:27:14Z
body: @jhernand the delete command won't result in the order disappearing from `fulfillment-cli get clusterorders`; but it looks like the order does disappear from the `cloudkit-operator-system` namespace - not sure if that's how it's supposed to work right now!
author_association: CONTRIBUTOR
user: login: coderabbitai[bot]
created_at: 2025-04-09T16:28:10Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
This change introduces a new deletion feature to the CLI application. A new command for deleting cluster orders is added under the delete command group. The implementation leverages the Cobra library to define a command that accepts exactly one argument, the cluster order ID. The command logic includes input validation, configuration loading, and establishing a gRPC connection. Through this connection, the corresponding cluster order is first retrieved and then deleted. The command integrates into the existing CLI structure by being added as a subcommand of the delete command, which is in turn incorporated into the root command.

## Possibly related PRs
- **innabox/fulfillment-cli#2**: Introduces new commands using Cobra for managing cluster orders, sharing similar command structure and context.

## Suggested reviewers
- **jhernand**

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEejqANiS4BBWvQYXsiGhXwUlfJVZoLWmWgMAOWxmAUouAFYDAFVECMhcAC9Q7QwMI31jcCgyenwAMxwCYjJlGgcWNgxOHj5BETFJaUg5BU8VNU1tXTBDEyg4VFRMYsJScioKv2raqgB3SERQ5jQKeTamDtV1LR0s7NMDeBrKDDQLAHoGZlpL7xIaa6cXSndPe5IfEgB9R2dXO9KH9bhoiPgOAYAEQwgwAYjhkBsAElSpNqHQlis1vJCoxYJhSIgjDZIORFkx/Bh6AV4FZIAADB40P4vQEeYE3Whg/AMyAEmQkMgoGpuWjYBiYk6JWAkRn/V5uDkUPncNAMADWaFIGhgCGQtPpSlp5GQaBmAUgBXckGZJyI6EYbMo/GVkGc9plcoAwoIqJALPABFR1rq4HLKatqShkPFcO7uJB5upYI7nNq5WrcK4sLgCfGKCQAI7YeCF5AkAAe6twFlx5HQFCIoXYABokwgGKnUHm5ciACL8Iq9p0Al1AvgEVpy5l0MOyi3UgDkFcrojw8HwWAs+CI8AYMcgZAYaG4ywsGPo0vNDIo2HSlF9p0ruD5LjvYnb8073eY3CsszICOt73nybB5ooGhmAuIEYGBjywIo057hgMjyBIFzwLQ1Cenm1BHtWYh1vwDZrM2syHrw+ASFhc6QMiRQYPguDtuo/B4NweBmlglBKpAbCIIgGboNGVbqEBC5UUQVDMLqyLxr2WCFrgFDwCQUgSRGVSWkwz7xpaO5oLQmkKBgtLNlMm5YB6GAOsBunmRoAAy+BGQAFAAlHyBT3k0W5ycOC4OfAFk4Vuh7MEgiCeqMRm0OWiCsQWjzYBQqEiUeFB8SctD7jhtkyvhI7OC6iCIdgFj0HeuYLkuO4oUui7ckYQRVixXr8QhSHSLgKiBmVLTmkQABKAAK3qmeQfnWdFBUjoZSiVGZIWpWFGByfGDCFhiZpOmpNRWjaI4Kq4rqeLGlA0ZKIn0NQNB/rgQH4JAymqepcojog3CiPAtKYhO7qzXZMEAOKPPBEHcvRgVyq9akYRYVraBYiUoMluCpeloy8e4AVYgwkqCT5FhJXU+CSnQT22l8jwfQuAM2cDcoMv2NM0BDiFQzYGDyDjFAVhgTD3q4mLiqpc36mThNmoWL0pWlmLJnm6DcFRvDwBinWCRmiC6jE3DhcsBPSIgxPUz4VntuawUUKs4jhQJQmkJR4vTFOn29dSaz5BxeBQQY4ZNUegunueO2ZXxBLUoGBXWnwwWhfb26ubltntiN42TaISdHi4fVILAsztgDcPqRcVvRnaW7tmQyzi8DRULiVfCFpKzTICccd280VpCrQAjqhqMpuNgRDlQpkluNL/tGAiSIWK4a1UyOSiOGsS9DgRBsUNMNqcQIgYHuw6hqcSBhQAAsl1t32HQXAMj5guQN6tyeZAABUTDBmgGi+lStB8mlGqTUwkGQnTeMqQBWAGQnBzBca4txPjfGeGOJUHxZyslQROEE3JwQMmhLCc+RxYFnHgVyJBtMKEsi5DySEMIoTwkRCiNE5RMTLH8OsTeXZCTSBJGSEgixDTMwwTQvB/I0CCmFLAsUEopQ1WZiQtKZDEGzlVIPDM85UBCOpiaQaQc46OkjAEMAMc5SKIKOqOUblvROWRB5QGuEFy+m/gGIMIZZDzmZi/ABVpfI5y2iQcOlplKY12uSeUfof5/yjD4k4edBZaWWhZTEU4o60HpCOKEs4oRNU8UHVAShEBbSDIrFMjoyruHjLKCwiYaAviWL1cQBUoSs2+HLRA+BUqSg0DkuwuUk4XDrKTE4TAKDbyCViAQRjoxtDip6MBzo0GUF/q/LyX4fx1GkKkA+8g0lWBMlXLAeJwH1GVLrPUcptEjKcIU8pntsIeCRMAhcTl9y1zlLKIyyyjCzyYQvcoVll4LlXheSyW5kB4irNvXefB96H2DuIcQvDz6QCvpDdAt9aD30fgebxb9P6RN/tpakUCeDqOdkyNmJBSUwNOEoq45DZxUN+KI3kBCGFELAEYRR5wGWILcMxHBtD2WMKRKiCYrD6DsNWJw45UciTQQjPKlo0jFCyI6nMnOeJzThOmVVL4l5EjPRXmzKyvjBYDMDLgeQ0pjrEtoCYk4Zi6UWO6ZAAAyt9Bgv08oWCGR1Sl3w+R6sPPAP8lTMQFDcMwANPLlF3FUWSkBztLQjExUajqArNr2oaR+DGss8QjhsciFW/48pJ00R3M0BMWBloGvQNo1zsCpyZq4hst4tkLw0H06JAQ3KzhWbQTyXkkwpltTBYa+BmLeT8ZbDs+5Uy6XfBKR6HVVjShDQYkcp4y0ngrRc/gUgqB+tzSu1KcpLRiRcJ6PVyBCzrusoLZVtAvxlJHLqnN4RPQkOkoa+IaBmD7MQMRWBxqgo5oQMoCgXYPE/NFTYf5YL0ru2BaIUFG9IWVmhf9WF2AD77gRSfZFUBe3RjinfRkA68UjqAeShRdLeUIITVSmlca+V3CzUKvBIqiGGAMAMYO+QihoDwOMMoUxMSRnYFwBYWIOEbHkFsZQOxuj7D6PxnIMx1A/CwogH4hYaICLoD8POO9eh8YEwAJgKAISzAA2AADAAZgYJEAAnA5tzdm7MAEYnM+YcyeOzDAAAcPnAkhZIIFtzAh3MCCcwAdkiAAFnoAcATkZtO6f0+pNS8xjN5HM0AA=== -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=innabox/fulfillment-cli&utm_content=5):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai plan` to trigger planning for file edits and PR creation.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: jhernand
created_at: 2025-04-09T18:07:49Z
body: > @jhernand the delete command won't result in the order disappearing from `fulfillment-cli get clusterorders`; but it looks like the order does disappear from the `cloudkit-operator-system` namespace - not sure if that's how it's supposed to work right now!

Yes @tzumainn, when you delete the cluster order from the API it is marked as deleted, and the corresponding Kubernetes object is also deleted. The logic to wait till the Kubernetes object is completely deleted and then delete the object from the database as well is missing.
author_association: CONTRIBUTOR