Skip to content

Commit 4b70629

Browse files
committed
feat(pilotctl): accept hostname/address/node-id in all identity ops
approve, reject, untrust, lookup, network invite/promote/demote/kick/role all now resolve node_id|pilot-address|hostname via resolveToNodeID. Update usage strings to reflect the wider accepted forms.
1 parent 6a5b159 commit 4b70629

1 file changed

Lines changed: 79 additions & 26 deletions

File tree

cmd/pilotctl/main.go

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,51 @@ func parseAddrOrHostname(d *driver.Driver, arg string) (protocol.Addr, error) {
565565
return resolved, nil
566566
}
567567

568+
// resolveToNodeID resolves any of: numeric node ID, pilot address
569+
// (N:NNNN.HHHH.LLLL), or hostname — to a uint32 node ID.
570+
// Prints a resolution line to stderr (text mode) so the user can see
571+
// what was matched. d may be nil only when the arg is numeric or an address.
572+
func resolveToNodeID(d *driver.Driver, arg string) uint32 {
573+
if id, err := strconv.ParseUint(arg, 10, 32); err == nil {
574+
return uint32(id)
575+
}
576+
if addr, err := protocol.ParseAddr(arg); err == nil {
577+
if !jsonOutput {
578+
fmt.Fprintf(os.Stderr, "parsed address %s → node %d\n", arg, addr.Node)
579+
}
580+
return addr.Node
581+
}
582+
if d == nil {
583+
fatalCode("invalid_argument", "cannot resolve hostname without a daemon connection: %q", arg)
584+
}
585+
_, nodeID, err := resolveHostnameToAddr(d, arg)
586+
if err != nil {
587+
fatalCode("not_found", "cannot resolve %q — check the hostname and that mutual trust exists", arg)
588+
}
589+
if !jsonOutput {
590+
fmt.Fprintf(os.Stderr, "resolved %q → node %d\n", arg, nodeID)
591+
}
592+
return nodeID
593+
}
594+
595+
// resolveNetworkNodeArg resolves a node ID, address, or hostname for network
596+
// subcommands that talk directly to the registry (no daemon connection kept open).
597+
// Opens a daemon connection only when the arg is a hostname.
598+
func resolveNetworkNodeArg(arg string) uint32 {
599+
if id, err := strconv.ParseUint(arg, 10, 32); err == nil {
600+
return uint32(id)
601+
}
602+
if addr, err := protocol.ParseAddr(arg); err == nil {
603+
if !jsonOutput {
604+
fmt.Fprintf(os.Stderr, "parsed address %s → node %d\n", arg, addr.Node)
605+
}
606+
return addr.Node
607+
}
608+
d := connectDriver()
609+
defer d.Close()
610+
return resolveToNodeID(d, arg)
611+
}
612+
568613
// hasHelpFlag returns true when args contains -h or --help.
569614
func hasHelpFlag(args []string) bool {
570615
for _, a := range args {
@@ -2527,14 +2572,25 @@ func cmdRegister(args []string) {
25272572

25282573
func cmdLookup(args []string) {
25292574
if len(args) < 1 {
2530-
fatalCode("invalid_argument", "usage: pilotctl lookup <node_id>")
2575+
fatalCode("invalid_argument", "usage: pilotctl lookup <node_id|address|hostname>")
25312576
}
2532-
flags, pos := parseFlags(args)
2577+
_, pos := parseFlags(args)
25332578
if len(pos) < 1 {
2534-
fatalCode("invalid_argument", "usage: pilotctl lookup <node_id>")
2579+
fatalCode("invalid_argument", "usage: pilotctl lookup <node_id|address|hostname>")
2580+
}
2581+
// Resolve hostname/address without a daemon connection when possible.
2582+
// If the arg is a hostname we need the daemon for resolution.
2583+
var nodeID uint32
2584+
arg := pos[0]
2585+
if id, err := strconv.ParseUint(arg, 10, 32); err == nil {
2586+
nodeID = uint32(id)
2587+
} else if addr, err := protocol.ParseAddr(arg); err == nil {
2588+
nodeID = addr.Node
2589+
} else {
2590+
d := connectDriver()
2591+
nodeID = resolveToNodeID(d, arg)
2592+
d.Close()
25352593
}
2536-
_ = flags
2537-
nodeID := parseNodeID(pos[0])
25382594
rc := connectRegistry()
25392595
defer rc.Close()
25402596
resp, err := rc.Lookup(nodeID)
@@ -3708,12 +3764,12 @@ func cmdHandshake(args []string) {
37083764

37093765
func cmdApprove(args []string) {
37103766
if len(args) < 1 {
3711-
fatalCode("invalid_argument", "usage: pilotctl approve <node_id>")
3767+
fatalCode("invalid_argument", "usage: pilotctl approve <node_id|address|hostname>")
37123768
}
37133769
d := connectDriver()
37143770
defer d.Close()
37153771

3716-
nodeID := parseNodeID(args[0])
3772+
nodeID := resolveToNodeID(d, args[0])
37173773

37183774
result, err := d.ApproveHandshake(nodeID)
37193775
if err != nil {
@@ -3730,12 +3786,12 @@ func cmdApprove(args []string) {
37303786

37313787
func cmdReject(args []string) {
37323788
if len(args) < 1 {
3733-
fatalCode("invalid_argument", "usage: pilotctl reject <node_id> [reason]")
3789+
fatalCode("invalid_argument", "usage: pilotctl reject <node_id|address|hostname> [reason]")
37343790
}
37353791
d := connectDriver()
37363792
defer d.Close()
37373793

3738-
nodeID := parseNodeID(args[0])
3794+
nodeID := resolveToNodeID(d, args[0])
37393795
reason := ""
37403796
if len(args) > 1 {
37413797
reason = args[1]
@@ -3755,17 +3811,13 @@ func cmdReject(args []string) {
37553811

37563812
func cmdUntrust(args []string) {
37573813
if len(args) < 1 {
3758-
fatalCode("invalid_argument", "usage: pilotctl untrust <node_id>")
3814+
fatalCode("invalid_argument", "usage: pilotctl untrust <node_id|address|hostname>")
37593815
}
3760-
nodeID, err := strconv.ParseUint(args[0], 10, 32)
3761-
if err != nil {
3762-
fatalCode("invalid_argument", "invalid node_id: %v", err)
3763-
}
3764-
37653816
d := connectDriver()
37663817
defer d.Close()
37673818

3768-
_, err = d.RevokeTrust(uint32(nodeID))
3819+
nodeID := resolveToNodeID(d, args[0])
3820+
_, err := d.RevokeTrust(nodeID)
37693821
if err != nil {
37703822
fatalCode("connection_failed", "untrust: %v", err)
37713823
}
@@ -5283,14 +5335,15 @@ func cmdNetworkMembers(args []string) {
52835335

52845336
func cmdNetworkInvite(args []string) {
52855337
if len(args) < 2 {
5286-
fatalCode("invalid_argument", "usage: pilotctl network invite <network_id> <node_id>")
5338+
fatalCode("invalid_argument", "usage: pilotctl network invite <network_id> <node_id|address|hostname>")
52875339
}
52885340
netID := parseUint16(args[0], "network_id")
5289-
nodeID := parseNodeID(args[1])
52905341

52915342
d := connectDriver()
52925343
defer d.Close()
52935344

5345+
nodeID := resolveToNodeID(d, args[1])
5346+
52945347
result, err := d.NetworkInvite(netID, nodeID)
52955348
if err != nil {
52965349
fatalCode("connection_failed", "network invite: %v", err)
@@ -5472,10 +5525,10 @@ func cmdNetworkRename(args []string) {
54725525

54735526
func cmdNetworkPromote(args []string) {
54745527
if len(args) < 2 {
5475-
fatalCode("invalid_argument", "usage: pilotctl network promote <network_id> <target_node_id>")
5528+
fatalCode("invalid_argument", "usage: pilotctl network promote <network_id> <node_id|address|hostname>")
54765529
}
54775530
netID := parseUint16(args[0], "network_id")
5478-
targetNodeID := parseNodeID(args[1])
5531+
targetNodeID := resolveNetworkNodeArg(args[1])
54795532
adminToken := requireAdminToken()
54805533

54815534
rc := connectRegistry()
@@ -5495,10 +5548,10 @@ func cmdNetworkPromote(args []string) {
54955548

54965549
func cmdNetworkDemote(args []string) {
54975550
if len(args) < 2 {
5498-
fatalCode("invalid_argument", "usage: pilotctl network demote <network_id> <target_node_id>")
5551+
fatalCode("invalid_argument", "usage: pilotctl network demote <network_id> <node_id|address|hostname>")
54995552
}
55005553
netID := parseUint16(args[0], "network_id")
5501-
targetNodeID := parseNodeID(args[1])
5554+
targetNodeID := resolveNetworkNodeArg(args[1])
55025555
adminToken := requireAdminToken()
55035556

55045557
rc := connectRegistry()
@@ -5517,10 +5570,10 @@ func cmdNetworkDemote(args []string) {
55175570

55185571
func cmdNetworkKick(args []string) {
55195572
if len(args) < 2 {
5520-
fatalCode("invalid_argument", "usage: pilotctl network kick <network_id> <target_node_id>")
5573+
fatalCode("invalid_argument", "usage: pilotctl network kick <network_id> <node_id|address|hostname>")
55215574
}
55225575
netID := parseUint16(args[0], "network_id")
5523-
targetNodeID := parseNodeID(args[1])
5576+
targetNodeID := resolveNetworkNodeArg(args[1])
55245577
adminToken := requireAdminToken()
55255578

55265579
rc := connectRegistry()
@@ -5539,10 +5592,10 @@ func cmdNetworkKick(args []string) {
55395592

55405593
func cmdNetworkRole(args []string) {
55415594
if len(args) < 2 {
5542-
fatalCode("invalid_argument", "usage: pilotctl network role <network_id> <node_id>")
5595+
fatalCode("invalid_argument", "usage: pilotctl network role <network_id> <node_id|address|hostname>")
55435596
}
55445597
netID := parseUint16(args[0], "network_id")
5545-
nodeID := parseNodeID(args[1])
5598+
nodeID := resolveNetworkNodeArg(args[1])
55465599

55475600
rc := connectRegistry()
55485601
defer rc.Close()

0 commit comments

Comments
 (0)