kubo/core/commands/name/ipnsps.go
Marcin Rataj 2260e35df2
chore: upgrade to go 1.23 (#10486)
* chore: upgrade to go 1.23

https://tip.golang.org/doc/go1.23

* refactor: golangci-lint v1.60.2
2024-08-28 18:56:45 +02:00

178 lines
4.1 KiB
Go

package name
import (
"fmt"
"io"
"strings"
cmds "github.com/ipfs/go-ipfs-cmds"
"github.com/ipfs/kubo/core/commands/cmdenv"
ke "github.com/ipfs/kubo/core/commands/keyencode"
record "github.com/libp2p/go-libp2p-record"
"github.com/libp2p/go-libp2p/core/peer"
)
type ipnsPubsubState struct {
Enabled bool
}
type ipnsPubsubCancel struct {
Canceled bool
}
type stringList struct {
Strings []string
}
// IpnsPubsubCmd is the subcommand that allows us to manage the IPNS pubsub system
var IpnsPubsubCmd = &cmds.Command{
Status: cmds.Experimental,
Helptext: cmds.HelpText{
Tagline: "IPNS pubsub management",
ShortDescription: `
Manage and inspect the state of the IPNS pubsub resolver.
Note: this command is experimental and subject to change as the system is refined
`,
},
Subcommands: map[string]*cmds.Command{
"state": ipnspsStateCmd,
"subs": ipnspsSubsCmd,
"cancel": ipnspsCancelCmd,
},
}
var ipnspsStateCmd = &cmds.Command{
Status: cmds.Experimental,
Helptext: cmds.HelpText{
Tagline: "Query the state of IPNS pubsub.",
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
if err != nil {
return err
}
return cmds.EmitOnce(res, &ipnsPubsubState{n.PSRouter != nil})
},
Type: ipnsPubsubState{},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ips *ipnsPubsubState) error {
var state string
if ips.Enabled {
state = "enabled"
} else {
state = "disabled"
}
_, err := fmt.Fprintln(w, state)
return err
}),
},
}
var ipnspsSubsCmd = &cmds.Command{
Status: cmds.Experimental,
Helptext: cmds.HelpText{
Tagline: "Show current name subscriptions.",
},
Options: []cmds.Option{
ke.OptionIPNSBase,
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
keyEnc, err := ke.KeyEncoderFromString(req.Options[ke.OptionIPNSBase.Name()].(string))
if err != nil {
return err
}
n, err := cmdenv.GetNode(env)
if err != nil {
return err
}
if n.PSRouter == nil {
return cmds.Errorf(cmds.ErrClient, "IPNS pubsub subsystem is not enabled")
}
var paths []string
for _, key := range n.PSRouter.GetSubscriptions() {
ns, k, err := record.SplitKey(key)
if err != nil || ns != "ipns" {
// Not necessarily an error.
continue
}
pid, err := peer.IDFromBytes([]byte(k))
if err != nil {
log.Errorf("ipns key not a valid peer ID: %s", err)
continue
}
paths = append(paths, "/ipns/"+keyEnc.FormatID(pid))
}
return cmds.EmitOnce(res, &stringList{paths})
},
Type: stringList{},
Encoders: cmds.EncoderMap{
cmds.Text: stringListEncoder(),
},
}
var ipnspsCancelCmd = &cmds.Command{
Status: cmds.Experimental,
Helptext: cmds.HelpText{
Tagline: "Cancel a name subscription.",
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
if err != nil {
return err
}
if n.PSRouter == nil {
return cmds.Errorf(cmds.ErrClient, "IPNS pubsub subsystem is not enabled")
}
name := req.Arguments[0]
name = strings.TrimPrefix(name, "/ipns/")
pid, err := peer.Decode(name)
if err != nil {
return cmds.Errorf(cmds.ErrClient, "not a valid IPNS name: %s", err)
}
ok, err := n.PSRouter.Cancel("/ipns/" + string(pid))
if err != nil {
return err
}
return cmds.EmitOnce(res, &ipnsPubsubCancel{ok})
},
Arguments: []cmds.Argument{
cmds.StringArg("name", true, false, "Name to cancel the subscription for."),
},
Type: ipnsPubsubCancel{},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, ipc *ipnsPubsubCancel) error {
var state string
if ipc.Canceled {
state = "canceled"
} else {
state = "no subscription"
}
_, err := fmt.Fprintln(w, state)
return err
}),
},
}
func stringListEncoder() cmds.EncoderFunc {
return cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, list *stringList) error {
for _, s := range list.Strings {
_, err := fmt.Fprintln(w, s)
if err != nil {
return err
}
}
return nil
})
}