Skip to content

Commit

Permalink
cli: Support deleting/updating individual Sources by name (#2479)
Browse files Browse the repository at this point in the history
Currently, the `odigos sources delete` and `odigos sources update`
commands only accept flags that identify Sources based on the Workload
they instrument. This is useful when the Source name might not be known
(such as Sources that were created with a random name by the UI), and it
also allows batch-deleting Sources (for example, deleting all Sources
that instrument a StatefulSet, etc)

This adds an optional argument to specify a Source explicity by its name
to these commands.

It also updates the help text (and docs) for these commands with
examples of usage in individual vs batch scenarios.
  • Loading branch information
damemi authored Feb 20, 2025
1 parent b63ba64 commit 1a02f9b
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 45 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ cli/odigos
serving-certs/
**/.tools/
**/LICENSES
odigos

**.tfstate
**.tfstate.backup
Expand Down
170 changes: 129 additions & 41 deletions cli/cmd/sources.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,70 +110,158 @@ var sourceCreateCmd = &cobra.Command{
}

var sourceDeleteCmd = &cobra.Command{
Use: "delete [flags]",
Use: "delete [name] [flags]",
Short: "Delete Odigos Sources",
Long: "This command will delete any Source objects that match the provided Workload info.",
Long: `This command will delete the named Source object or any Source objects that match the provided Workload info.
If a [name] is provided, that Source object will be deleted in the given namespace using the --namespace (-n) flag.
For example, to delete the Source named "mysource-abc123" in namespace "myapp", run:
$ odigos sources delete mysource-abc123 -n myapp
Multiple Source objects can be deleted at once using the --workload-name, --workload-kind, and --workload-namespace flags.
These flags are AND-ed so that if any of these flags are provided, all Sources that match the given flags will be deleted.
For example, to delete all Sources for StatefulSet workloads in the cluster, run:
$ odigos sources delete --workload-kind=StatefulSet --all-namespaces
To delete all Deployment Sources in namespace Foobar, run:
$ odigos sources delete --workload-kind=Deployment --workload-namespace=Foobar
or
$ odigos sources delete --workload-kind=Deployment -n Foobar
These flags can be used to batch delete Sources, or as an alternative to deleting a Source by name (for instance, when
the name of the Source might not be known, but the Workload information is known). For example:
$ odigos sources delete --workload-kind=Deployment --workload-name=myapp -n myapp-namespace
This command will delete any Sources in the namespace "myapp-namespace" that instrument a Deployment named "myapp"
It is important to note that if a Source [name] is provided, all --workload-* flags will be ignored to delete only the named Source.
`,
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ctx := cmd.Context()
client := cmdcontext.KubeClientFromContextOrExit(ctx)

namespaceText, providedWorkloadFlags, namespaceList, labelSet := parseSourceLabelFlags()

if !cmd.Flag("yes").Changed {
fmt.Printf("About to delete all Sources in %s that match:\n%s", namespaceText, providedWorkloadFlags)
confirmed, err := confirm.Ask("Are you sure?")
if err != nil || !confirmed {
fmt.Println("Aborting delete")
return
if len(args) > 0 {
sourceName := args[0]
fmt.Printf("Deleting Source %s in namespace %s\n", sourceName, sourceNamespaceFlag)
err := client.OdigosClient.Sources(sourceNamespaceFlag).Delete(ctx, sourceName, v1.DeleteOptions{})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot delete source %s in namespace %s: %+v\n", sourceName, sourceNamespaceFlag, err)
os.Exit(1)
} else {
fmt.Printf("Deleted source %s in namespace %s\n", sourceName, sourceNamespaceFlag)
}
} else {
namespaceText, providedWorkloadFlags, namespaceList, labelSet := parseSourceLabelFlags()

if !cmd.Flag("yes").Changed {
fmt.Printf("About to delete all Sources in %s that match:\n%s", namespaceText, providedWorkloadFlags)
confirmed, err := confirm.Ask("Are you sure?")
if err != nil || !confirmed {
fmt.Println("Aborting delete")
return
}
}
}

sources, err := client.OdigosClient.Sources(namespaceList).List(ctx, v1.ListOptions{LabelSelector: labelSet.AsSelector().String()})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot list Sources: %+v\n", err)
os.Exit(1)
}

deletedCount := 0
for _, source := range sources.Items {
err := client.OdigosClient.Sources(source.GetNamespace()).Delete(ctx, source.GetName(), v1.DeleteOptions{})
sources, err := client.OdigosClient.Sources(namespaceList).List(ctx, v1.ListOptions{LabelSelector: labelSet.AsSelector().String()})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot delete Sources %s/%s: %+v\n", source.GetNamespace(), source.GetName(), err)
fmt.Printf("\033[31mERROR\033[0m Cannot list Sources: %+v\n", err)
os.Exit(1)
}
fmt.Printf("Deleted Source %s/%s\n", source.GetNamespace(), source.GetName())
deletedCount++

deletedCount := 0
for _, source := range sources.Items {
err := client.OdigosClient.Sources(source.GetNamespace()).Delete(ctx, source.GetName(), v1.DeleteOptions{})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot delete Sources %s/%s: %+v\n", source.GetNamespace(), source.GetName(), err)
os.Exit(1)
}
fmt.Printf("Deleted Source %s/%s\n", source.GetNamespace(), source.GetName())
deletedCount++
}
fmt.Printf("Deleted %d Sources\n", deletedCount)
}
fmt.Printf("Deleted %d Sources\n", deletedCount)
},
}

var sourceUpdateCmd = &cobra.Command{
Use: "update [flags]",
Use: "update [name] [flags]",
Short: "Update Odigos Sources",
Long: "This command will update any Source objects that match the provided Workload info.",
Long: `This command will update the named Source object or any Source objects that match the provided Workload info.
If a [name] is provided, that Source object will be updated in the given namespace using the --namespace (-n) flag.
For example, to update the Source named "mysource-abc123" in namespace "myapp", run:
$ odigos sources update mysource-abc123 -n myapp <flags>
Multiple Source objects can be updated at once using the --workload-name, --workload-kind, and --workload-namespace flags.
These flags are AND-ed so that if any of these flags are provided, all Sources that match the given flags will be updated.
For example, to update all Sources for StatefulSet workloads in the cluster, run:
$ odigos sources update --workload-kind=StatefulSet --all-namespaces <flags>
To update all Deployment Sources in namespace Foobar, run:
$ odigos sources update --workload-kind=Deployment --workload-namespace=Foobar <flags>
or
$ odigos sources update --workload-kind=Deployment -n Foobar <flags>
These flags can be used to batch update Sources, or as an alternative to updating a Source by name (for instance, when
the name of the Source might not be known, but the Workload information is known). For example:
$ odigos sources update --workload-kind=Deployment --workload-name=myapp -n myapp-namespace <flags>
This command will update any Sources in the namespace "myapp-namespace" that instrument a Deployment named "myapp"
It is important to note that if a Source [name] is provided, all --workload-* flags will be ignored to update only the named Source.
`,
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
ctx := cmd.Context()
client := cmdcontext.KubeClientFromContextOrExit(ctx)

namespaceText, providedWorkloadFlags, namespaceList, labelSet := parseSourceLabelFlags()

if !cmd.Flag("yes").Changed {
fmt.Printf("About to update all Sources in %s that match:\n%s", namespaceText, providedWorkloadFlags)
confirmed, err := confirm.Ask("Are you sure?")
if err != nil || !confirmed {
fmt.Println("Aborting delete")
return
sourceList := &v1alpha1.SourceList{}
if len(args) > 0 {
sourceName := args[0]
sources, err := client.OdigosClient.Sources(sourceNamespaceFlag).List(ctx, v1.ListOptions{FieldSelector: "metadata.name=" + sourceName})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot list Source %s: %+v\n", sourceName, err)
os.Exit(1)
}
sourceList = sources
} else {
namespaceText, providedWorkloadFlags, namespaceList, labelSet := parseSourceLabelFlags()

if !cmd.Flag("yes").Changed {
fmt.Printf("About to update all Sources in %s that match:\n%s", namespaceText, providedWorkloadFlags)
confirmed, err := confirm.Ask("Are you sure?")
if err != nil || !confirmed {
fmt.Println("Aborting update")
return
}
}
}

sources, err := client.OdigosClient.Sources(namespaceList).List(ctx, v1.ListOptions{LabelSelector: labelSet.AsSelector().String()})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot list Sources: %+v\n", err)
os.Exit(1)
sources, err := client.OdigosClient.Sources(namespaceList).List(ctx, v1.ListOptions{LabelSelector: labelSet.AsSelector().String()})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot list Sources: %+v\n", err)
os.Exit(1)
}
sourceList = sources
}

for _, source := range sources.Items {
for _, source := range sourceList.Items {
source.Spec.DisableInstrumentation = disableInstrumentationFlag
if len(sourceRemoveGroupFlag) > 0 {
for label, value := range source.Labels {
Expand All @@ -193,7 +281,7 @@ var sourceUpdateCmd = &cobra.Command{
source.Spec.OtelServiceName = sourceOtelServiceFlag
}

_, err := client.OdigosClient.Sources(namespaceList).Update(ctx, &source, v1.UpdateOptions{})
_, err := client.OdigosClient.Sources(source.GetNamespace()).Update(ctx, &source, v1.UpdateOptions{})
if err != nil {
fmt.Printf("\033[31mERROR\033[0m Cannot update Sources %s/%s: %+v\n", source.GetNamespace(), source.GetName(), err)
os.Exit(1)
Expand Down
35 changes: 33 additions & 2 deletions docs/cli/odigos_sources_delete.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,41 @@ Delete Odigos Sources

### Synopsis

This command will delete any Source objects that match the provided Workload info.
This command will delete the named Source object or any Source objects that match the provided Workload info.

If a [name] is provided, that Source object will be deleted in the given namespace using the --namespace (-n) flag.

For example, to delete the Source named "mysource-abc123" in namespace "myapp", run:

$ odigos sources delete mysource-abc123 -n myapp

Multiple Source objects can be deleted at once using the --workload-name, --workload-kind, and --workload-namespace flags.
These flags are AND-ed so that if any of these flags are provided, all Sources that match the given flags will be deleted.

For example, to delete all Sources for StatefulSet workloads in the cluster, run:

$ odigos sources delete --workload-kind=StatefulSet --all-namespaces

To delete all Deployment Sources in namespace Foobar, run:

$ odigos sources delete --workload-kind=Deployment --workload-namespace=Foobar

or

$ odigos sources delete --workload-kind=Deployment -n Foobar

These flags can be used to batch delete Sources, or as an alternative to deleting a Source by name (for instance, when
the name of the Source might not be known, but the Workload information is known). For example:

$ odigos sources delete --workload-kind=Deployment --workload-name=myapp -n myapp-namespace

This command will delete any Sources in the namespace "myapp-namespace" that instrument a Deployment named "myapp"

It is important to note that if a Source [name] is provided, all --workload-* flags will be ignored to delete only the named Source.


```
odigos sources delete [flags]
odigos sources delete [name] [flags]
```

### Options
Expand Down
35 changes: 33 additions & 2 deletions docs/cli/odigos_sources_update.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,41 @@ Update Odigos Sources

### Synopsis

This command will update any Source objects that match the provided Workload info.
This command will update the named Source object or any Source objects that match the provided Workload info.

If a [name] is provided, that Source object will be updated in the given namespace using the --namespace (-n) flag.

For example, to update the Source named "mysource-abc123" in namespace "myapp", run:

$ odigos sources update mysource-abc123 -n myapp <flags>

Multiple Source objects can be updated at once using the --workload-name, --workload-kind, and --workload-namespace flags.
These flags are AND-ed so that if any of these flags are provided, all Sources that match the given flags will be updated.

For example, to update all Sources for StatefulSet workloads in the cluster, run:

$ odigos sources update --workload-kind=StatefulSet --all-namespaces <flags>

To update all Deployment Sources in namespace Foobar, run:

$ odigos sources update --workload-kind=Deployment --workload-namespace=Foobar <flags>

or

$ odigos sources update --workload-kind=Deployment -n Foobar <flags>

These flags can be used to batch update Sources, or as an alternative to updating a Source by name (for instance, when
the name of the Source might not be known, but the Workload information is known). For example:

$ odigos sources update --workload-kind=Deployment --workload-name=myapp -n myapp-namespace <flags>

This command will update any Sources in the namespace "myapp-namespace" that instrument a Deployment named "myapp"

It is important to note that if a Source [name] is provided, all --workload-* flags will be ignored to update only the named Source.


```
odigos sources update [flags]
odigos sources update [name] [flags]
```

### Options
Expand Down

0 comments on commit 1a02f9b

Please sign in to comment.