Skip to content

Commit 3689639

Browse files
committed
Add ExtendNodeExpiration functionality to gRPC and CLI
Implement ExtendNodeExpiration RPC, allowing users to extend a node's expiration. Update the CLI to include the `extend-expiration` command with required fields. Validate inputs, update the database, and notify peers of expiration changes.
1 parent bcd80ee commit 3689639

File tree

9 files changed

+721
-231
lines changed

9 files changed

+721
-231
lines changed

cmd/headscale/cli/nodes.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/samber/lo"
1717
"github.com/spf13/cobra"
1818
"google.golang.org/grpc/status"
19+
"google.golang.org/protobuf/types/known/timestamppb"
1920
"tailscale.com/types/key"
2021
)
2122

@@ -58,6 +59,18 @@ func init() {
5859
}
5960
nodeCmd.AddCommand(expireNodeCmd)
6061

62+
extendNodeExpirationCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)")
63+
err = extendNodeExpirationCmd.MarkFlagRequired("identifier")
64+
if err != nil {
65+
log.Fatal(err.Error())
66+
}
67+
extendNodeExpirationCmd.Flags().StringP("new-expiry", "e", "", "New expiration time in RFC3339 format, e.g., 2024-01-01T15:04:05Z")
68+
err = extendNodeExpirationCmd.MarkFlagRequired("new-expiry")
69+
if err != nil {
70+
log.Fatal(err.Error())
71+
}
72+
nodeCmd.AddCommand(extendNodeExpirationCmd)
73+
6174
renameNodeCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)")
6275
err = renameNodeCmd.MarkFlagRequired("identifier")
6376
if err != nil {
@@ -320,6 +333,54 @@ var expireNodeCmd = &cobra.Command{
320333
},
321334
}
322335

336+
var extendNodeExpirationCmd = &cobra.Command{
337+
Use: "extend-expiration",
338+
Short: "Extends the expiration of a node by setting a new expiration time",
339+
Run: func(cmd *cobra.Command, args []string) {
340+
output, _ := cmd.Flags().GetString("output")
341+
nodeID, err := cmd.Flags().GetUint64("identifier")
342+
if err != nil {
343+
ErrorOutput(err, fmt.Sprintf("Error getting identifier from flag: %s", err), output)
344+
}
345+
346+
newExpiryStr, err := cmd.Flags().GetString("new-expiry")
347+
if err != nil {
348+
ErrorOutput(err, fmt.Sprintf("Error getting new-expiry from flag: %s", err), output)
349+
}
350+
351+
// Parse the new-expiry timestamp from string to time.Time
352+
newExpiry, err := time.Parse(time.RFC3339, newExpiryStr)
353+
if err != nil {
354+
ErrorOutput(err, fmt.Sprintf("Invalid expiration time format: must be in RFC3339 format, %s", err), output)
355+
}
356+
357+
// Set up context and gRPC client
358+
ctx, client, conn, cancel := newHeadscaleCLIWithConfig()
359+
defer cancel()
360+
defer conn.Close()
361+
362+
// Build the gRPC request
363+
request := &v1.ExtendNodeExpirationRequest{
364+
NodeId: nodeID,
365+
NewExpiration: timestamppb.New(newExpiry), // convert time.Time to protobuf timestamp
366+
}
367+
368+
// Make the gRPC call
369+
response, err := client.ExtendNodeExpiration(ctx, request)
370+
if err != nil {
371+
st, ok := status.FromError(err)
372+
if ok {
373+
ErrorOutput(st.Err(), st.Message(), output)
374+
} else {
375+
ErrorOutput(err, "Unexpected error during ExtendNodeExpiration RPC call", output)
376+
}
377+
}
378+
379+
// Print the result
380+
SuccessOutput(response, "Node expiration extended successfully", output)
381+
},
382+
}
383+
323384
var renameNodeCmd = &cobra.Command{
324385
Use: "rename NEW_NAME",
325386
Short: "Renames a node in your network",

gen/go/headscale/v1/headscale.pb.go

Lines changed: 91 additions & 86 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)