Reservation lease time; reservations by MAC address or client ID
- A reservation can have its own lease time (--lease-time, the reservation dialog), over the subnet's. Schema migration 6. - A reservation with a MAC address and a client ID matches either one (a dual-boot machine sends two client IDs from one MAC); before, it was found by MAC and then refused. A lease of the reserved address by the client's other identity counts as its own. - The Leases page shows a client's client ID; reserving a lease uses both, or one with --by / the dialog's choice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
abb2ee0fd7
commit
4fd72998ec
20 files changed
+252
-65
No files matched your search
+10
-2
@@ -126,13 +126,17 @@ gets a NAK when it next renews, and then asks for a new address.`,
|
||||
}
|
||||
del.Flags().BoolVarP(&yes, "yes", "y", false, "don't ask")
|
||||
cmd.AddCommand(del)
|
||||
var hostname, comment string
|
||||
var hostname, comment, by string
|
||||
reserve := &cobra.Command{
|
||||
Use: "reserve IP",
|
||||
Short: "Make a lease's address its client's reservation",
|
||||
Long: `Makes the address a client has now its reservation: it keeps it from
|
||||
then on. The host name the client sent becomes the reservation's, unless
|
||||
--hostname gives another.`,
|
||||
--hostname gives another.
|
||||
|
||||
The reservation knows the client by its MAC address and, if it sent one,
|
||||
its client ID (option 61): either one gets it the address. --by mac or
|
||||
--by client-id uses just one.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
c, err := newClient()
|
||||
@@ -146,6 +150,9 @@ then on. The host name the client sent becomes the reservation's, unless
|
||||
if comment != "" {
|
||||
body["comment"] = comment
|
||||
}
|
||||
if by != "" {
|
||||
body["by"] = by
|
||||
}
|
||||
var resp api.MutationResponse
|
||||
if err := c.Do(ctx(), "POST", "/leases/"+args[0]+"/reserve", nil, body, &resp); err != nil {
|
||||
return err
|
||||
@@ -155,6 +162,7 @@ then on. The host name the client sent becomes the reservation's, unless
|
||||
}
|
||||
reserve.Flags().StringVar(&hostname, "hostname", "", "the reservation's host name")
|
||||
reserve.Flags().StringVar(&comment, "comment", "", "a comment")
|
||||
reserve.Flags().StringVar(&by, "by", "", "know the client by mac, client-id or both (the default)")
|
||||
cmd.AddCommand(reserve)
|
||||
return cmd
|
||||
}
|
||||
|
||||
+32
-8
@@ -385,7 +385,7 @@ func reservationCmd() *cobra.Command {
|
||||
for _, r := range rs {
|
||||
who := r.MAC
|
||||
if r.ClientID != "" {
|
||||
who = "id " + r.ClientID
|
||||
who = strings.TrimPrefix(r.MAC+" or id "+r.ClientID, " or ")
|
||||
}
|
||||
lease := "-"
|
||||
if r.Lease != nil {
|
||||
@@ -427,6 +427,11 @@ func reservationCmd() *cobra.Command {
|
||||
}
|
||||
fmt.Fprintf(w, "Host name:\t%s\n", orDash(r.Hostname))
|
||||
fmt.Fprintln(w, "Options:\t"+optionsText(r.Options))
|
||||
lt := "the subnet's"
|
||||
if r.LeaseTime > 0 {
|
||||
lt = fmtSeconds(r.LeaseTime)
|
||||
}
|
||||
fmt.Fprintf(w, "Lease time:\t%s\n", lt)
|
||||
if r.Lease != nil {
|
||||
fmt.Fprintf(w, "Lease:\tuntil %s, on %s\n", r.Lease.End.Local().Format("2006-01-02 15:04"), r.Lease.Interface)
|
||||
if r.Lease.LastSeen != nil {
|
||||
@@ -467,17 +472,18 @@ func reservationCmd() *cobra.Command {
|
||||
})
|
||||
}
|
||||
|
||||
var hostname, clientID, comment, ip, mac string
|
||||
var hostname, clientID, comment, ip, mac, leaseTime string
|
||||
var opts, unsetOpts []string
|
||||
add := &cobra.Command{
|
||||
Use: "add IP MAC",
|
||||
Short: "Reserve an address for a client",
|
||||
Long: `Reserves an address for a client, known by its MAC address (or by its
|
||||
client identifier: give "-" for the MAC and --client-id). The address picks
|
||||
the subnet. An address inside a pool is fine: it is never handed out to
|
||||
anyone else.
|
||||
Long: `Reserves an address for a client, known by its MAC address, its client
|
||||
identifier (option 61: give "-" for the MAC and --client-id), or both:
|
||||
then either one gets it the address, as for a machine that boots two
|
||||
systems. The address picks the subnet. An address inside a pool is fine:
|
||||
it is never handed out to anyone else.
|
||||
|
||||
steward reservation add 10.0.10.20 aa:bb:cc:dd:ee:01 --hostname nas`,
|
||||
steward reservation add 10.0.10.20 aa:bb:cc:dd:ee:01 --hostname nas --lease-time 7d`,
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
c, err := newClient()
|
||||
@@ -497,6 +503,13 @@ anyone else.
|
||||
if comment != "" {
|
||||
in.Comment = &comment
|
||||
}
|
||||
if leaseTime != "" {
|
||||
n, err := parseSeconds(leaseTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
in.LeaseTime = &n
|
||||
}
|
||||
if len(opts) > 0 {
|
||||
o, err := optionsArg(opts)
|
||||
if err != nil {
|
||||
@@ -513,7 +526,8 @@ anyone else.
|
||||
}
|
||||
f := add.Flags()
|
||||
f.StringVar(&hostname, "hostname", "", "the host name to send it")
|
||||
f.StringVar(&clientID, "client-id", "", "match the client identifier (hex) instead of the MAC address")
|
||||
f.StringVar(&clientID, "client-id", "", "the client identifier (hex): with a MAC address, either one matches")
|
||||
f.StringVar(&leaseTime, "lease-time", "", "this client's lease time (12h, 7d; default: the subnet's)")
|
||||
f.StringArrayVar(&opts, "option", nil, "an option NAME=VALUE for this client only")
|
||||
f.StringVar(&comment, "comment", "", "a comment")
|
||||
cmd.AddCommand(add)
|
||||
@@ -547,6 +561,15 @@ anyone else.
|
||||
if fl.Changed("comment") {
|
||||
in.Comment = &comment
|
||||
}
|
||||
if fl.Changed("lease-time") {
|
||||
n := 0
|
||||
if leaseTime != "default" {
|
||||
if n, err = parseSeconds(leaseTime); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
in.LeaseTime = &n
|
||||
}
|
||||
if len(opts) > 0 || len(unsetOpts) > 0 {
|
||||
set, err := optionsArg(opts)
|
||||
if err != nil {
|
||||
@@ -570,6 +593,7 @@ anyone else.
|
||||
f.StringVar(&mac, "mac", "", "a new MAC address (\"\" for none)")
|
||||
f.StringVar(&clientID, "client-id", "", "a client identifier (\"\" for none)")
|
||||
f.StringVar(&hostname, "hostname", "", "a new host name")
|
||||
f.StringVar(&leaseTime, "lease-time", "", "lease time (12h, 7d, or \"default\": the subnet's)")
|
||||
f.StringArrayVar(&opts, "option", nil, "set an option NAME=VALUE")
|
||||
f.StringArrayVar(&unsetOpts, "unset-option", nil, "remove an option")
|
||||
f.StringVar(&comment, "comment", "", "a comment")
|
||||
|
||||
Reference in new issue
Block a user