1package structs
2
3import (
4	"fmt"
5	"time"
6
7	"github.com/hashicorp/raft"
8)
9
10// RaftServer has information about a server in the Raft configuration.
11type RaftServer struct {
12	// ID is the unique ID for the server. These are currently the same
13	// as the address, but they will be changed to a real GUID in a future
14	// release of Nomad.
15	ID raft.ServerID
16
17	// Node is the node name of the server, as known by Nomad, or this
18	// will be set to "(unknown)" otherwise.
19	Node string
20
21	// Address is the IP:port of the server, used for Raft communications.
22	Address raft.ServerAddress
23
24	// Leader is true if this server is the current cluster leader.
25	Leader bool
26
27	// Voter is true if this server has a vote in the cluster. This might
28	// be false if the server is staging and still coming online, or if
29	// it's a non-voting server, which will be added in a future release of
30	// Nomad.
31	Voter bool
32
33	// RaftProtocol is the version of the Raft protocol spoken by this server.
34	RaftProtocol string
35}
36
37// RaftConfigurationResponse is returned when querying for the current Raft
38// configuration.
39type RaftConfigurationResponse struct {
40	// Servers has the list of servers in the Raft configuration.
41	Servers []*RaftServer
42
43	// Index has the Raft index of this configuration.
44	Index uint64
45}
46
47// RaftPeerByAddressRequest is used by the Operator endpoint to apply a Raft
48// operation on a specific Raft peer by address in the form of "IP:port".
49type RaftPeerByAddressRequest struct {
50	// Address is the peer to remove, in the form "IP:port".
51	Address raft.ServerAddress
52
53	// WriteRequest holds the Region for this request.
54	WriteRequest
55}
56
57// RaftPeerByIDRequest is used by the Operator endpoint to apply a Raft
58// operation on a specific Raft peer by ID.
59type RaftPeerByIDRequest struct {
60	// ID is the peer ID to remove.
61	ID raft.ServerID
62
63	// WriteRequest holds the Region for this request.
64	WriteRequest
65}
66
67// AutopilotSetConfigRequest is used by the Operator endpoint to update the
68// current Autopilot configuration of the cluster.
69type AutopilotSetConfigRequest struct {
70	// Datacenter is the target this request is intended for.
71	Datacenter string
72
73	// Config is the new Autopilot configuration to use.
74	Config AutopilotConfig
75
76	// CAS controls whether to use check-and-set semantics for this request.
77	CAS bool
78
79	// WriteRequest holds the ACL token to go along with this request.
80	WriteRequest
81}
82
83// RequestDatacenter returns the datacenter for a given request.
84func (op *AutopilotSetConfigRequest) RequestDatacenter() string {
85	return op.Datacenter
86}
87
88// AutopilotConfig is the internal config for the Autopilot mechanism.
89type AutopilotConfig struct {
90	// CleanupDeadServers controls whether to remove dead servers when a new
91	// server is added to the Raft peers.
92	CleanupDeadServers bool
93
94	// ServerStabilizationTime is the minimum amount of time a server must be
95	// in a stable, healthy state before it can be added to the cluster. Only
96	// applicable with Raft protocol version 3 or higher.
97	ServerStabilizationTime time.Duration
98
99	// LastContactThreshold is the limit on the amount of time a server can go
100	// without leader contact before being considered unhealthy.
101	LastContactThreshold time.Duration
102
103	// MaxTrailingLogs is the amount of entries in the Raft Log that a server can
104	// be behind before being considered unhealthy.
105	MaxTrailingLogs uint64
106
107	// MinQuorum sets the minimum number of servers required in a cluster
108	// before autopilot can prune dead servers.
109	MinQuorum uint
110
111	// (Enterprise-only) EnableRedundancyZones specifies whether to enable redundancy zones.
112	EnableRedundancyZones bool
113
114	// (Enterprise-only) DisableUpgradeMigration will disable Autopilot's upgrade migration
115	// strategy of waiting until enough newer-versioned servers have been added to the
116	// cluster before promoting them to voters.
117	DisableUpgradeMigration bool
118
119	// (Enterprise-only) EnableCustomUpgrades specifies whether to enable using custom
120	// upgrade versions when performing migrations.
121	EnableCustomUpgrades bool
122
123	// CreateIndex/ModifyIndex store the create/modify indexes of this configuration.
124	CreateIndex uint64
125	ModifyIndex uint64
126}
127
128// SchedulerAlgorithm is an enum string that encapsulates the valid options for a
129// SchedulerConfiguration stanza's SchedulerAlgorithm. These modes will allow the
130// scheduler to be user-selectable.
131type SchedulerAlgorithm string
132
133const (
134	// SchedulerAlgorithmBinpack indicates that the scheduler should spread
135	// allocations as evenly as possible over the available hardware.
136	SchedulerAlgorithmBinpack SchedulerAlgorithm = "binpack"
137
138	// SchedulerAlgorithmSpread indicates that the scheduler should spread
139	// allocations as evenly as possible over the available hardware.
140	SchedulerAlgorithmSpread SchedulerAlgorithm = "spread"
141)
142
143// SchedulerConfiguration is the config for controlling scheduler behavior
144type SchedulerConfiguration struct {
145	// SchedulerAlgorithm lets you select between available scheduling algorithms.
146	SchedulerAlgorithm SchedulerAlgorithm `hcl:"scheduler_algorithm"`
147
148	// PreemptionConfig specifies whether to enable eviction of lower
149	// priority jobs to place higher priority jobs.
150	PreemptionConfig PreemptionConfig `hcl:"preemption_config"`
151
152	MemoryOversubscriptionEnabled bool `hcl:"memory_oversubscription_enabled"`
153
154	// CreateIndex/ModifyIndex store the create/modify indexes of this configuration.
155	CreateIndex uint64
156	ModifyIndex uint64
157}
158
159func (s *SchedulerConfiguration) EffectiveSchedulerAlgorithm() SchedulerAlgorithm {
160	if s == nil || s.SchedulerAlgorithm == "" {
161		return SchedulerAlgorithmBinpack
162	}
163
164	return s.SchedulerAlgorithm
165}
166
167func (s *SchedulerConfiguration) Canonicalize() {
168	if s != nil && s.SchedulerAlgorithm == "" {
169		s.SchedulerAlgorithm = SchedulerAlgorithmBinpack
170	}
171}
172
173func (s *SchedulerConfiguration) Validate() error {
174	if s == nil {
175		return nil
176	}
177
178	switch s.SchedulerAlgorithm {
179	case "", SchedulerAlgorithmBinpack, SchedulerAlgorithmSpread:
180	default:
181		return fmt.Errorf("invalid scheduler algorithm: %v", s.SchedulerAlgorithm)
182	}
183
184	return nil
185}
186
187// SchedulerConfigurationResponse is the response object that wraps SchedulerConfiguration
188type SchedulerConfigurationResponse struct {
189	// SchedulerConfig contains scheduler config options
190	SchedulerConfig *SchedulerConfiguration
191
192	QueryMeta
193}
194
195// SchedulerSetConfigurationResponse is the response object used
196// when updating scheduler configuration
197type SchedulerSetConfigurationResponse struct {
198	// Updated returns whether the config was actually updated
199	// Only set when the request uses CAS
200	Updated bool
201
202	WriteMeta
203}
204
205// PreemptionConfig specifies whether preemption is enabled based on scheduler type
206type PreemptionConfig struct {
207	// SystemSchedulerEnabled specifies if preemption is enabled for system jobs
208	SystemSchedulerEnabled bool `hcl:"system_scheduler_enabled"`
209
210	// BatchSchedulerEnabled specifies if preemption is enabled for batch jobs
211	BatchSchedulerEnabled bool `hcl:"batch_scheduler_enabled"`
212
213	// ServiceSchedulerEnabled specifies if preemption is enabled for service jobs
214	ServiceSchedulerEnabled bool `hcl:"service_scheduler_enabled"`
215}
216
217// SchedulerSetConfigRequest is used by the Operator endpoint to update the
218// current Scheduler configuration of the cluster.
219type SchedulerSetConfigRequest struct {
220	// Config is the new Scheduler configuration to use.
221	Config SchedulerConfiguration
222
223	// CAS controls whether to use check-and-set semantics for this request.
224	CAS bool
225
226	// WriteRequest holds the ACL token to go along with this request.
227	WriteRequest
228}
229
230// SnapshotSaveRequest is used by the Operator endpoint to get a Raft snapshot
231type SnapshotSaveRequest struct {
232	QueryOptions
233}
234
235// SnapshotSaveResponse is the header for the streaming snapshot endpoint,
236// and followed by the snapshot file content.
237type SnapshotSaveResponse struct {
238
239	// SnapshotChecksum returns the checksum of snapshot file in the format
240	// `<algo>=<base64>` (e.g. `sha-256=...`)
241	SnapshotChecksum string
242
243	// ErrorCode is an http error code if an error is found, e.g. 403 for permission errors
244	ErrorCode int `codec:",omitempty"`
245
246	// ErrorMsg is the error message if an error is found, e.g. "Permission Denied"
247	ErrorMsg string `codec:",omitempty"`
248
249	QueryMeta
250}
251
252type SnapshotRestoreRequest struct {
253	WriteRequest
254}
255
256type SnapshotRestoreResponse struct {
257	ErrorCode int    `codec:",omitempty"`
258	ErrorMsg  string `codec:",omitempty"`
259
260	QueryMeta
261}
262