From d51d6b811d75a7399ae71108ffe1a08f81a691e7 Mon Sep 17 00:00:00 2001 From: gene-redpanda <123959009+gene-redpanda@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:28:14 -0500 Subject: [PATCH] feat: add mountable Adds mountable --- src/go/rpk/go.mod | 2 +- src/go/rpk/go.sum | 4 +- src/go/rpk/pkg/cli/cluster/storage/BUILD | 1 + .../rpk/pkg/cli/cluster/storage/list-mount.go | 2 +- .../pkg/cli/cluster/storage/list-mountable.go | 85 +++++++++++++++++++ src/go/rpk/pkg/cli/cluster/storage/mount.go | 4 +- src/go/rpk/pkg/cli/cluster/storage/storage.go | 1 + src/go/rpk/pkg/cli/cluster/storage/unmount.go | 2 +- 8 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/go/rpk/pkg/cli/cluster/storage/list-mountable.go diff --git a/src/go/rpk/go.mod b/src/go/rpk/go.mod index 23a7c9d510d61..949b0c20300e4 100644 --- a/src/go/rpk/go.mod +++ b/src/go/rpk/go.mod @@ -38,7 +38,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/client_model v0.6.1 github.com/prometheus/common v0.59.1 - github.com/redpanda-data/common-go/rpadmin v0.1.7 + github.com/redpanda-data/common-go/rpadmin v0.1.10 github.com/rs/xid v1.6.0 github.com/safchain/ethtool v0.4.1 github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 diff --git a/src/go/rpk/go.sum b/src/go/rpk/go.sum index a2c0e4d575f31..af42c0a8b1837 100644 --- a/src/go/rpk/go.sum +++ b/src/go/rpk/go.sum @@ -209,8 +209,8 @@ github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJ github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= github.com/redpanda-data/common-go/net v0.1.0 h1:JnJioRJuL961r1QXiJQ1tW9+yEaJfu8FpXnUmvQbwNM= github.com/redpanda-data/common-go/net v0.1.0/go.mod h1:iOdNkjxM7a1T8F3cYHTaKIPFCHzzp/ia6TN+Z+7Tt5w= -github.com/redpanda-data/common-go/rpadmin v0.1.7 h1:zj3HiZuvAdOvOdi7oyTn4FYOPulO7BhvhLx9acOy810= -github.com/redpanda-data/common-go/rpadmin v0.1.7/go.mod h1:I7umqhnMhIOSEnIA3fvLtdQU7QO/SbWGCwFfFDs3De4= +github.com/redpanda-data/common-go/rpadmin v0.1.10 h1:3j/iRfqVglmmotE5bL0OF/3zwnrBwKZNHnnaTyA1bGU= +github.com/redpanda-data/common-go/rpadmin v0.1.10/go.mod h1:I7umqhnMhIOSEnIA3fvLtdQU7QO/SbWGCwFfFDs3De4= github.com/redpanda-data/go-avro/v2 v2.0.0-20240405204525-77b1144dc525 h1:vskZrV6q8W8flL0Ud23AJUYAd8ZgTadO45+loFnG2G0= github.com/redpanda-data/go-avro/v2 v2.0.0-20240405204525-77b1144dc525/go.mod h1:3YqAM7pgS5vW/EH7naCjFqnAajSgi0f0CfMe1HGhLxQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= diff --git a/src/go/rpk/pkg/cli/cluster/storage/BUILD b/src/go/rpk/pkg/cli/cluster/storage/BUILD index 3f31204d6eae5..7dbb37ec5c0a8 100644 --- a/src/go/rpk/pkg/cli/cluster/storage/BUILD +++ b/src/go/rpk/pkg/cli/cluster/storage/BUILD @@ -5,6 +5,7 @@ go_library( srcs = [ "cancel-mount.go", "list-mount.go", + "list-mountable.go", "mount.go", "status-mount.go", "storage.go", diff --git a/src/go/rpk/pkg/cli/cluster/storage/list-mount.go b/src/go/rpk/pkg/cli/cluster/storage/list-mount.go index b26ad9d3eb739..f4c83f46fa281 100644 --- a/src/go/rpk/pkg/cli/cluster/storage/list-mount.go +++ b/src/go/rpk/pkg/cli/cluster/storage/list-mount.go @@ -146,7 +146,7 @@ func rpadminMigrationStateToMigrationState(in []rpadmin.MigrationState) (resp [] // rpadminTopicsToStringSlice converts a slice of rpadmin.NamespacedTopic to a slice of strings // if the topic has a non nil namespace it will appear as `namespace:topic` // otherwise it will appear as `topic`. -func rpadminTopicsToStringSlice(in []rpadmin.NamespacedTopic) (resp []string) { +func rpadminTopicsToStringSlice(in []rpadmin.NamespacedOrInboundTopic) (resp []string) { for _, entry := range in { if entry.Namespace != nil { resp = append(resp, fmt.Sprintf("%s/%s", *entry.Namespace, entry.Topic)) diff --git a/src/go/rpk/pkg/cli/cluster/storage/list-mountable.go b/src/go/rpk/pkg/cli/cluster/storage/list-mountable.go new file mode 100644 index 0000000000000..a24febdc6ec3e --- /dev/null +++ b/src/go/rpk/pkg/cli/cluster/storage/list-mountable.go @@ -0,0 +1,85 @@ +package storage + +import ( + "fmt" + "io" + "os" + + "github.com/redpanda-data/common-go/rpadmin" + "github.com/redpanda-data/redpanda/src/go/rpk/pkg/adminapi" + "github.com/redpanda-data/redpanda/src/go/rpk/pkg/config" + "github.com/redpanda-data/redpanda/src/go/rpk/pkg/out" + "github.com/spf13/afero" + "github.com/spf13/cobra" +) + +func newListMountable(fs afero.Fs, p *config.Params) *cobra.Command { + cmd := &cobra.Command{ + Use: "list-mountable", + Short: "List mountable topics from object storage", + Long: `List topics that are available to mount from object storage. + +This command displays topics that exist in object storage and can be mounted +to your Redpanda cluster. Each topic includes its location in object storage +and namespace information if applicable.`, + Example: ` +List all mountable topics: + rpk cluster storage list-mountable +`, + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, _ []string) { + f := p.Formatter + if h, ok := f.Help([]mountableTopicState{}); ok { + out.Exit(h) + } + + pf, err := p.LoadVirtualProfile(fs) + out.MaybeDie(err, "rpk unable to load config: %v", err) + config.CheckExitCloudAdmin(pf) + adm, err := adminapi.NewClient(cmd.Context(), fs, pf) + out.MaybeDie(err, "unable to initialize admin client: %v", err) + + response, err := adm.ListMountableTopics(cmd.Context()) + out.MaybeDie(err, "unable to list mountable topics: %v", err) + printDetailedListMountable(p.Formatter, rpadminMountableTopicsToMountableTopicState(response.Topics), os.Stdout) + }, + } + p.InstallFormatFlag(cmd) + return cmd +} + +func printDetailedListMountable(f config.OutFormatter, d []mountableTopicState, w io.Writer) { + if isText, _, t, err := f.Format(d); !isText { + out.MaybeDie(err, "unable to print in the requested format %q: %v", f.Kind, err) + fmt.Fprintln(w, t) + return + } + tw := out.NewTableTo(w, "Topic", "Namespace", "Location") + defer tw.Flush() + for _, m := range d { + namespace := "kafka" // default namespace + if m.Namespace != nil { + namespace = *m.Namespace + } + tw.Print(m.Topic, namespace, m.TopicLocation) + } +} + +type mountableTopicState struct { + Topic string `json:"topic" yaml:"topic"` + Namespace *string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + TopicLocation string `json:"topic_location" yaml:"topic_location"` +} + +func rpadminMountableTopicsToMountableTopicState(in []rpadmin.MountableTopic) []mountableTopicState { + resp := make([]mountableTopicState, 0, len(in)) + for _, entry := range in { + state := mountableTopicState{ + Topic: entry.Topic, + Namespace: entry.Namespace, + TopicLocation: entry.TopicLocation, + } + resp = append(resp, state) + } + return resp +} diff --git a/src/go/rpk/pkg/cli/cluster/storage/mount.go b/src/go/rpk/pkg/cli/cluster/storage/mount.go index 256ae01ad8e9b..aa69213b0a9d5 100644 --- a/src/go/rpk/pkg/cli/cluster/storage/mount.go +++ b/src/go/rpk/pkg/cli/cluster/storage/mount.go @@ -57,7 +57,7 @@ with my-new-topic as the new topic name out.Die("topic is required") } topic := rpadmin.InboundTopic{ - SourceTopic: rpadmin.NamespacedTopic{ + SourceTopicReference: rpadmin.NamespacedTopic{ Namespace: string2pointer(n), Topic: t, }, @@ -78,7 +78,7 @@ with my-new-topic as the new topic name fmt.Printf(` Topic mount from Tiered Storage topic %v to your Redpanda Cluster topic %v has started with Migration ID %v -To check the status run 'rpk cluster storage status-mount %d'\n`, t, alias, mg.ID, mg.ID) +To check the status run 'rpk cluster storage status-mount %d`+"\n", t, alias, mg.ID, mg.ID) }, } cmd.Flags().StringVar(&to, "to", "", "New namespace/topic name for the mounted topic (optional)") diff --git a/src/go/rpk/pkg/cli/cluster/storage/storage.go b/src/go/rpk/pkg/cli/cluster/storage/storage.go index d779f0b1eea15..a9436a93b8325 100644 --- a/src/go/rpk/pkg/cli/cluster/storage/storage.go +++ b/src/go/rpk/pkg/cli/cluster/storage/storage.go @@ -28,6 +28,7 @@ func NewCommand(fs afero.Fs, p *config.Params) *cobra.Command { newMountList(fs, p), newMountStatus(fs, p), newMountCancel(fs, p), + newListMountable(fs, p), ) return cmd } diff --git a/src/go/rpk/pkg/cli/cluster/storage/unmount.go b/src/go/rpk/pkg/cli/cluster/storage/unmount.go index e30b2416f7606..dadb3b65be1da 100644 --- a/src/go/rpk/pkg/cli/cluster/storage/unmount.go +++ b/src/go/rpk/pkg/cli/cluster/storage/unmount.go @@ -62,7 +62,7 @@ Unmount topic 'my-topic' from the cluster in the 'my-namespace' fmt.Printf(` Topic unmounting from your Redpanda Cluster topic %v has started with Migration ID %v -To check the status run 'rpk cluster storage status-mount %d'\n`, t, mg.ID, mg.ID) +To check the status run 'rpk cluster storage status-mount %d`+"\n", t, mg.ID, mg.ID) }, } return cmd