|
|
|
|
@ -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())
|
|
|
|
|
|