open-nomad/nomad/client_meta_endpoint.go
Michael Schurter 35d65c7c7e
Dynamic Node Metadata (#15844)
Fixes #14617
Dynamic Node Metadata allows Nomad users, and their jobs, to update Node metadata through an API. Currently Node metadata is only reloaded when a Client agent is restarted.

Includes new UI for editing metadata as well.

---------

Co-authored-by: Phil Renaud <phil.renaud@hashicorp.com>
2023-02-07 14:42:25 -08:00

70 lines
1.8 KiB
Go

package nomad
import (
"time"
metrics "github.com/armon/go-metrics"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/nomad/nomad/structs"
nstructs "github.com/hashicorp/nomad/nomad/structs"
)
type NodeMeta struct {
srv *Server
logger log.Logger
}
func newNodeMetaEndpoint(srv *Server) *NodeMeta {
n := &NodeMeta{
srv: srv,
logger: srv.logger.Named("node_meta"),
}
return n
}
func (n *NodeMeta) Apply(args *structs.NodeMetaApplyRequest, reply *structs.NodeMetaResponse) error {
const method = "NodeMeta.Apply"
authErr := n.srv.Authenticate(nil, args)
if done, err := n.srv.forward(method, args, args, reply); done {
return err
}
n.srv.MeasureRPCRate("node_meta", nstructs.RateMetricRead, args)
if authErr != nil {
return nstructs.ErrPermissionDenied
}
defer metrics.MeasureSince([]string{"nomad", "client_meta", "apply"}, time.Now())
// Check node write permissions
if aclObj, err := n.srv.ResolveACL(args); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNodeWrite() {
return nstructs.ErrPermissionDenied
}
return n.srv.forwardClientRPC(method, args.NodeID, args, reply)
}
func (n *NodeMeta) Read(args *structs.NodeSpecificRequest, reply *structs.NodeMetaResponse) error {
const method = "NodeMeta.Read"
authErr := n.srv.Authenticate(nil, args)
if done, err := n.srv.forward(method, args, args, reply); done {
return err
}
n.srv.MeasureRPCRate("node_meta", nstructs.RateMetricRead, args)
if authErr != nil {
return nstructs.ErrPermissionDenied
}
defer metrics.MeasureSince([]string{"nomad", "client_meta", "read"}, time.Now())
// Check node read permissions
if aclObj, err := n.srv.ResolveACL(args); err != nil {
return err
} else if aclObj != nil && !aclObj.AllowNodeRead() {
return nstructs.ErrPermissionDenied
}
return n.srv.forwardClientRPC(method, args.NodeID, args, reply)
}