Files
nomad/api/scaling.go
Tim Gross cd3101d624 scale: add -check-index to job scale command (#23457)
The RPC handler for scaling a job passes flags to enforce the job modify index
is unchanged when it makes the write to Raft. But its only checking against the
existing job modify index at the time the RPC handler snapshots the state store,
so it can only enforce consistency for its own validation.

In clusters with automated scaling, it would be useful to expose the enforce
index options to the API, so that cluster admins can enforce that scaling only
happens when the job state is consistent with a state they've previously seen in
other API calls. Add this option to the CLI and API and have the RPC handler
check them if asked.

Fixes: https://github.com/hashicorp/nomad/issues/23444
2024-06-27 16:54:06 -04:00

128 lines
3.1 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package api
const (
// ScalingPolicyTypeHorizontal indicates a policy that does horizontal scaling.
ScalingPolicyTypeHorizontal = "horizontal"
)
// Scaling is used to query scaling-related API endpoints
type Scaling struct {
client *Client
}
// Scaling returns a handle on the scaling endpoints.
func (c *Client) Scaling() *Scaling {
return &Scaling{client: c}
}
func (s *Scaling) ListPolicies(q *QueryOptions) ([]*ScalingPolicyListStub, *QueryMeta, error) {
var resp []*ScalingPolicyListStub
qm, err := s.client.query("/v1/scaling/policies", &resp, q)
if err != nil {
return nil, nil, err
}
return resp, qm, nil
}
func (s *Scaling) GetPolicy(id string, q *QueryOptions) (*ScalingPolicy, *QueryMeta, error) {
var policy ScalingPolicy
qm, err := s.client.query("/v1/scaling/policy/"+id, &policy, q)
if err != nil {
return nil, nil, err
}
return &policy, qm, nil
}
func (p *ScalingPolicy) Canonicalize(taskGroupCount int) {
if p.Enabled == nil {
p.Enabled = pointerOf(true)
}
if p.Min == nil {
var m int64 = int64(taskGroupCount)
p.Min = &m
}
if p.Type == "" {
p.Type = ScalingPolicyTypeHorizontal
}
}
// ScalingRequest is the payload for a generic scaling action
type ScalingRequest struct {
Count *int64
Target map[string]string
Message string
Error bool
Meta map[string]interface{}
WriteRequest
// this is effectively a job update, so we need the ability to override policy.
PolicyOverride bool
// If JobModifyIndex is set then the job will only be scaled if it matches
// the current Jobs index. The JobModifyIndex is ignored if 0.
JobModifyIndex uint64
}
// ScalingPolicy is the user-specified API object for an autoscaling policy
type ScalingPolicy struct {
/* fields set by user in HCL config */
Min *int64 `hcl:"min,optional"`
Max *int64 `hcl:"max,optional"`
Policy map[string]interface{} `hcl:"policy,block"`
Enabled *bool `hcl:"enabled,optional"`
Type string `hcl:"type,optional"`
/* fields set by server */
ID string
Namespace string
Target map[string]string
CreateIndex uint64
ModifyIndex uint64
}
// ScalingPolicyListStub is used to return a subset of scaling policy information
// for the scaling policy list
type ScalingPolicyListStub struct {
ID string
Enabled bool
Type string
Target map[string]string
CreateIndex uint64
ModifyIndex uint64
}
// JobScaleStatusResponse is used to return information about job scaling status
type JobScaleStatusResponse struct {
JobID string
Namespace string
JobCreateIndex uint64
JobModifyIndex uint64
JobStopped bool
TaskGroups map[string]TaskGroupScaleStatus
}
type TaskGroupScaleStatus struct {
Desired int
Placed int
Running int
Healthy int
Unhealthy int
Events []ScalingEvent
}
type ScalingEvent struct {
Count *int64
PreviousCount int64
Error bool
Message string
Meta map[string]interface{}
EvalID *string
Time uint64
CreateIndex uint64
}