|
|
|
|
@ -1643,6 +1643,56 @@ func (c *Direct) ReportHealthChange(w *health.Warnable, us *health.UnhealthyStat |
|
|
|
|
res.Body.Close() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetDeviceAttrs does a synchronous call to the control plane to update
|
|
|
|
|
// the node's attributes.
|
|
|
|
|
//
|
|
|
|
|
// See docs on [tailcfg.SetDeviceAttributesRequest] for background.
|
|
|
|
|
func (c *Auto) SetDeviceAttrs(ctx context.Context, attrs tailcfg.AttrUpdate) error { |
|
|
|
|
return c.direct.SetDeviceAttrs(ctx, attrs) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetDeviceAttrs does a synchronous call to the control plane to update
|
|
|
|
|
// the node's attributes.
|
|
|
|
|
//
|
|
|
|
|
// See docs on [tailcfg.SetDeviceAttributesRequest] for background.
|
|
|
|
|
func (c *Direct) SetDeviceAttrs(ctx context.Context, attrs tailcfg.AttrUpdate) error { |
|
|
|
|
nc, err := c.getNoiseClient() |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
nodeKey, ok := c.GetPersist().PublicNodeKeyOK() |
|
|
|
|
if !ok { |
|
|
|
|
return errors.New("no node key") |
|
|
|
|
} |
|
|
|
|
if c.panicOnUse { |
|
|
|
|
panic("tainted client") |
|
|
|
|
} |
|
|
|
|
req := &tailcfg.SetDeviceAttributesRequest{ |
|
|
|
|
NodeKey: nodeKey, |
|
|
|
|
Version: tailcfg.CurrentCapabilityVersion, |
|
|
|
|
Update: attrs, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(bradfitz): unify the callers using doWithBody vs those using
|
|
|
|
|
// DoNoiseRequest. There seems to be a ~50/50 split and they're very close,
|
|
|
|
|
// but doWithBody sets the load balancing header and auto-JSON-encodes the
|
|
|
|
|
// body, but DoNoiseRequest is exported. Clean it up so they're consistent
|
|
|
|
|
// one way or another.
|
|
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, 30*time.Second) |
|
|
|
|
defer cancel() |
|
|
|
|
res, err := nc.doWithBody(ctx, "PATCH", "/machine/set-device-attr", nodeKey, req) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
defer res.Body.Close() |
|
|
|
|
all, _ := io.ReadAll(res.Body) |
|
|
|
|
if res.StatusCode != 200 { |
|
|
|
|
return fmt.Errorf("HTTP error from control plane: %v: %s", res.Status, all) |
|
|
|
|
} |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func addLBHeader(req *http.Request, nodeKey key.NodePublic) { |
|
|
|
|
if !nodeKey.IsZero() { |
|
|
|
|
req.Header.Add(tailcfg.LBHeader, nodeKey.String()) |
|
|
|
|
|