1syntax = "proto3";
2
3package docker.swarmkit.v1;
4
5import "google/protobuf/timestamp.proto";
6import "google/protobuf/duration.proto";
7import "gogoproto/gogo.proto";
8
9// This file contains types that are common to objects and spec or that are not
10// considered first-class within the cluster object-model.
11
12// Version tracks the last time an object in the store was updated.
13message Version {
14	uint64 index = 1;
15}
16
17message IndexEntry {
18	string key = 1;
19	string val = 2;
20}
21
22// Annotations provide useful information to identify API objects. They are
23// common to all API specs.
24message Annotations {
25	string name = 1;
26	map<string, string> labels = 2;
27
28	// Indices provides keys and values for indexing this object.
29	// A single key may have multiple values.
30	repeated IndexEntry indices = 4 [(gogoproto.nullable) = false];
31}
32
33// NamedGenericResource represents a "user defined" resource which is defined
34// as a string.
35// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
36// Value is used to identify the resource (GPU="UUID-1", FPGA="/dev/sdb5", ...)
37message NamedGenericResource {
38	string kind = 1;
39	string value = 2;
40}
41
42// DiscreteGenericResource represents a "user defined" resource which is defined
43// as an integer
44// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
45// Value is used to count the resource (SSD=5, HDD=3, ...)
46message DiscreteGenericResource {
47	string kind = 1;
48	int64 value = 2;
49}
50
51// GenericResource represents a "user defined" resource which can
52// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1)
53message GenericResource {
54	oneof resource {
55		NamedGenericResource named_resource_spec = 1;
56		DiscreteGenericResource discrete_resource_spec = 2;
57	}
58}
59
60enum ResourceType {
61	TASK = 0;
62	SECRET = 1;
63	CONFIG = 2;
64}
65
66message Resources {
67	// Amount of CPUs (e.g. 2000000000 = 2 CPU cores)
68	int64 nano_cpus = 1 [(gogoproto.customname) = "NanoCPUs"];
69
70	// Amount of memory in bytes.
71	int64 memory_bytes = 2;
72
73	// User specified resource (e.g: bananas=2;apple={red,yellow,green})
74	repeated GenericResource generic = 3;
75}
76
77message ResourceRequirements {
78	Resources limits = 1;
79	Resources reservations = 2;
80}
81
82message Platform {
83	// Architecture (e.g. x86_64)
84	string architecture = 1;
85
86	// Operating System (e.g. linux)
87	string os = 2 [(gogoproto.customname) = "OS"];
88}
89
90// PluginDescription describes an engine plugin.
91message PluginDescription {
92	// Type of plugin. Canonical values for existing types are
93	// Volume, Network, and Authorization. More types could be
94	// supported in the future.
95	string type = 1;
96
97	// Name of the plugin
98	string name = 2;
99}
100
101message EngineDescription {
102	// Docker daemon version running on the node.
103	string engine_version = 1;
104
105	// Labels attached to the engine.
106	map<string, string> labels = 2;
107
108	// Volume, Network, and Auth plugins
109	repeated PluginDescription plugins = 3 [(gogoproto.nullable) = false];
110}
111
112message NodeDescription {
113	// Hostname of the node as reported by the agent.
114	// This is different from spec.meta.name which is user-defined.
115	string hostname = 1;
116
117	// Platform of the node.
118	Platform platform = 2;
119
120	// Total resources on the node.
121	Resources resources = 3;
122
123	// Information about the Docker Engine on the node.
124	EngineDescription engine = 4;
125
126	// Information on the node's TLS setup
127	NodeTLSInfo tls_info = 5 [(gogoproto.customname) = "TLSInfo"];
128
129	// FIPS indicates whether the node has FIPS-enabled
130	bool fips = 6 [(gogoproto.customname) = "FIPS"];
131}
132
133message NodeTLSInfo {
134	// Information about which root certs the node trusts
135	bytes trust_root = 1;
136
137	// Information about the node's current TLS certificate
138	bytes cert_issuer_subject = 2;
139	bytes cert_issuer_public_key = 3;
140}
141
142message RaftMemberStatus {
143	bool leader = 1;
144
145	enum Reachability {
146		// Unknown indicates that the manager state cannot be resolved
147		UNKNOWN = 0;
148
149		// Unreachable indicates that the node cannot be contacted by other
150		// raft cluster members.
151		UNREACHABLE = 1;
152
153		// Reachable indicates that the node is healthy and reachable
154		// by other members.
155		REACHABLE = 2;
156	}
157
158	Reachability reachability = 2;
159	string message = 3;
160}
161
162message NodeStatus {
163	// TODO(aluzzardi) These should be using `gogoproto.enumvalue_customname`.
164	enum State {
165		// Unknown indicates the node state cannot be resolved.
166		UNKNOWN = 0;
167
168		// Down indicates the node is down.
169		DOWN = 1;
170
171		// Ready indicates the node is ready to accept tasks.
172		READY = 2;
173
174		// Disconnected indicates the node is currently trying to find new manager.
175		DISCONNECTED = 3;
176	}
177
178	State state = 1;
179	string message = 2;
180	// Addr is the node's IP address as observed by the manager
181	string addr = 3;
182}
183
184message Image {
185	// reference is a docker image reference. This can include a rpository, tag
186	// or be fully qualified witha digest. The format is specified in the
187	// distribution/reference package.
188	string reference = 1;
189}
190
191// Mount describes volume mounts for a container.
192//
193// The Mount type follows the structure of the mount syscall, including a type,
194// source, target. Top-level flags, such as writable, are common to all kinds
195// of mounts, where we also provide options that are specific to a type of
196// mount. This corresponds to flags and data, respectively, in the syscall.
197message Mount {
198	enum Type {
199		option (gogoproto.goproto_enum_prefix) = false;
200		option (gogoproto.enum_customname) = "MountType";
201
202		BIND = 0 [(gogoproto.enumvalue_customname) = "MountTypeBind"]; // Bind mount host dir
203		VOLUME = 1 [(gogoproto.enumvalue_customname) = "MountTypeVolume"];  // Remote storage volumes
204		TMPFS = 2 [(gogoproto.enumvalue_customname) = "MountTypeTmpfs"]; // Mount a tmpfs
205	}
206
207	// Type defines the nature of the mount.
208	Type type = 1;
209
210	// Source specifies the name of the mount. Depending on mount type, this
211	// may be a volume name or a host path, or even ignored.
212	string source = 2;
213
214	// Target path in container
215	string target = 3;
216
217	// ReadOnly should be set to true if the mount should not be writable.
218	bool readonly = 4 [(gogoproto.customname) = "ReadOnly"];
219
220	// Consistency indicates the tolerable level of file system consistency
221	enum Consistency {
222		option (gogoproto.goproto_enum_prefix) = false;
223		option (gogoproto.enum_customname) = "MountConsistency";
224
225		DEFAULT = 0 [(gogoproto.enumvalue_customname) = "MountConsistencyDefault"];
226		CONSISTENT = 1 [(gogoproto.enumvalue_customname) = "MountConsistencyFull"];
227		CACHED = 2 [(gogoproto.enumvalue_customname) = "MountConsistencyCached"];
228		DELEGATED = 3 [(gogoproto.enumvalue_customname) = "MountConsistencyDelegated"];
229	}
230	Consistency consistency = 8;
231
232	// BindOptions specifies options that are specific to a bind mount.
233	message BindOptions {
234		enum Propagation {
235			option (gogoproto.goproto_enum_prefix) = false;
236			option (gogoproto.enum_customname) = "MountPropagation";
237
238			RPRIVATE = 0 [(gogoproto.enumvalue_customname) = "MountPropagationRPrivate"];
239			PRIVATE = 1 [(gogoproto.enumvalue_customname) = "MountPropagationPrivate"];
240			RSHARED = 2 [(gogoproto.enumvalue_customname) = "MountPropagationRShared"];
241			SHARED = 3 [(gogoproto.enumvalue_customname) = "MountPropagationShared"];
242			RSLAVE = 4 [(gogoproto.enumvalue_customname) = "MountPropagationRSlave"];
243			SLAVE = 5 [(gogoproto.enumvalue_customname) = "MountPropagationSlave"];
244		}
245
246		// Propagation mode of mount.
247		Propagation propagation = 1;
248	}
249
250	// VolumeOptions contains parameters for mounting the volume.
251	message VolumeOptions {
252		// nocopy prevents automatic copying of data to the volume with data from target
253		bool nocopy = 1 [(gogoproto.customname) = "NoCopy"];
254
255		// labels to apply to the volume if creating
256		map<string, string> labels = 2;
257
258		// DriverConfig specifies the options that may be passed to the driver
259		// if the volume is created.
260		//
261		// If this is empty, no volume will be created if the volume is missing.
262		Driver driver_config = 3;
263	}
264
265	message TmpfsOptions {
266		// Size sets the size of the tmpfs, in bytes.
267		//
268		// This will be converted to an operating system specific value
269		// depending on the host. For example, on linux, it will be convered to
270		// use a 'k', 'm' or 'g' syntax. BSD, though not widely supported with
271		// docker, uses a straight byte value.
272		//
273		// Percentages are not supported.
274		int64 size_bytes = 1;
275
276		// Mode of the tmpfs upon creation
277		uint32 mode = 2 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false];
278
279		// TODO(stevvooe): There are several more tmpfs flags, specified in the
280		// daemon, that are accepted. Only the most basic are added for now.
281		//
282		// From docker/docker/pkg/mount/flags.go:
283		//
284		// var validFlags = map[string]bool{
285		// 	"":          true,
286		// 	"size":      true, X
287		// 	"mode":      true, X
288		// 	"uid":       true,
289		// 	"gid":       true,
290		// 	"nr_inodes": true,
291		// 	"nr_blocks": true,
292		// 	"mpol":      true,
293		// }
294		//
295		// Some of these may be straightforward to add, but others, such as
296		// uid/gid have implications in a clustered system.
297	}
298
299	// Depending on type, one of bind_options or volumes_options will be set.
300
301	// BindOptions configures properties of a bind mount type.
302	//
303	// For mounts of type bind, the source must be an absolute host path.
304	BindOptions bind_options = 5;
305
306	// VolumeOptions configures the properties specific to a volume mount type.
307	//
308	// For mounts of type volume, the source will be used as the volume name.
309	VolumeOptions volume_options = 6;
310
311	// TmpfsOptions allows one to set options for mounting a temporary
312	// filesystem.
313	//
314	// The source field will be ignored when using mounts of type tmpfs.
315	TmpfsOptions tmpfs_options = 7;
316
317	// TODO(stevvooe): It be better to use a oneof field above, although the
318	// type is enough to make the decision, while being primary to the
319	// datastructure.
320}
321
322message RestartPolicy {
323	enum RestartCondition {
324		option (gogoproto.goproto_enum_prefix) = false;
325		option (gogoproto.enum_customname) = "RestartCondition";
326		NONE = 0 [(gogoproto.enumvalue_customname) = "RestartOnNone"];
327		ON_FAILURE = 1 [(gogoproto.enumvalue_customname) = "RestartOnFailure"];
328		ANY = 2 [(gogoproto.enumvalue_customname) = "RestartOnAny"];
329	}
330
331	RestartCondition condition = 1;
332
333	// Delay between restart attempts
334	// Note: can't use stdduration because this field needs to be nullable.
335	google.protobuf.Duration delay = 2;
336
337	// MaxAttempts is the maximum number of restarts to attempt on an
338	// instance before giving up. Ignored if 0.
339	uint64 max_attempts = 3;
340
341	// Window is the time window used to evaluate the restart policy.
342	// The time window is unbounded if this is 0.
343	// Note: can't use stdduration because this field needs to be nullable.
344	google.protobuf.Duration window = 4;
345}
346
347// UpdateConfig specifies the rate and policy of updates.
348// TODO(aluzzardi): Consider making this a oneof with RollingStrategy and LockstepStrategy.
349message UpdateConfig {
350	// Maximum number of tasks to be updated in one iteration.
351	// 0 means unlimited parallelism.
352	uint64 parallelism = 1;
353
354	// Amount of time between updates.
355	google.protobuf.Duration delay = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];
356
357	enum FailureAction {
358		PAUSE = 0;
359		CONTINUE = 1;
360		ROLLBACK = 2;
361	}
362
363	// FailureAction is the action to take when an update failures.
364	FailureAction failure_action = 3;
365
366	// Monitor indicates how long to monitor a task for failure after it is
367	// created. If the task fails by ending up in one of the states
368	// REJECTED, COMPLETED, or FAILED, within Monitor from its creation,
369	// this counts as a failure. If it fails after Monitor, it does not
370	// count as a failure. If Monitor is unspecified, a default value will
371	// be used.
372	// Note: can't use stdduration because this field needs to be nullable.
373	google.protobuf.Duration monitor = 4;
374
375	// MaxFailureRatio is the fraction of tasks that may fail during
376	// an update before the failure action is invoked. Any task created by
377	// the current update which ends up in one of the states REJECTED,
378	// COMPLETED or FAILED within Monitor from its creation counts as a
379	// failure. The number of failures is divided by the number of tasks
380	// being updated, and if this fraction is greater than
381	// MaxFailureRatio, the failure action is invoked.
382	//
383	// If the failure action is CONTINUE, there is no effect.
384	// If the failure action is PAUSE, no more tasks will be updated until
385	// another update is started.
386	// If the failure action is ROLLBACK, the orchestrator will attempt to
387	// roll back to the previous service spec. If the MaxFailureRatio
388	// threshold is hit during the rollback, the rollback will pause.
389	float max_failure_ratio = 5;
390
391	// UpdateOrder controls the order of operations when rolling out an
392	// updated task. Either the old task is shut down before the new task
393	// is started, or the new task is started before the old task is shut
394	// down.
395	enum UpdateOrder {
396		STOP_FIRST = 0;
397		START_FIRST = 1;
398	}
399
400	UpdateOrder order = 6;
401}
402
403// UpdateStatus is the status of an update in progress.
404message UpdateStatus {
405	enum UpdateState {
406		UNKNOWN = 0;
407		UPDATING = 1;
408		PAUSED = 2;
409		COMPLETED = 3;
410		ROLLBACK_STARTED = 4;
411		ROLLBACK_PAUSED = 5; // if a rollback fails
412		ROLLBACK_COMPLETED = 6;
413	}
414
415	// State is the state of this update. It indicates whether the
416	// update is in progress, completed, paused, rolling back, or
417	// finished rolling back.
418	UpdateState state = 1;
419
420	// StartedAt is the time at which the update was started.
421	// Note: can't use stdtime because this field is nullable.
422	google.protobuf.Timestamp started_at = 2;
423
424	// CompletedAt is the time at which the update completed successfully,
425	// paused, or finished rolling back.
426	// Note: can't use stdtime because this field is nullable.
427	google.protobuf.Timestamp completed_at = 3;
428
429	// TODO(aaronl): Consider adding a timestamp showing when the most
430	// recent task update took place. Currently, this is nontrivial
431	// because each service update kicks off a replacement update, so
432	// updating the service object with a timestamp at every step along
433	// the rolling update would cause the rolling update to be constantly
434	// restarted.
435
436	// Message explains how the update got into its current state. For
437	// example, if the update is paused, it will explain what is preventing
438	// the update from proceeding (typically the failure of a task to start up
439	// when OnFailure is PAUSE).
440	string message = 4;
441}
442
443// TaskState enumerates the states that a task progresses through within an
444// agent. States are designed to be monotonically increasing, such that if two
445// states are seen by a task, the greater of the new represents the true state.
446
447// Only the manager create a NEW task, and move the task to PENDING and ASSIGNED.
448// Afterward, the manager must rely on the agent to update the task status
449// (pre-run: preparing, ready, starting;
450//  running;
451//  end-state: complete, shutdown, failed, rejected)
452enum TaskState {
453	// TODO(aluzzardi): Move it back into `TaskStatus` because of the naming
454	// collisions of enums.
455
456	option (gogoproto.goproto_enum_prefix) = false;
457	option (gogoproto.enum_customname) = "TaskState";
458	NEW = 0 [(gogoproto.enumvalue_customname)="TaskStateNew"];
459	PENDING = 64 [(gogoproto.enumvalue_customname)="TaskStatePending"]; // waiting for scheduling decision
460	ASSIGNED = 192 [(gogoproto.enumvalue_customname)="TaskStateAssigned"];
461	ACCEPTED = 256 [(gogoproto.enumvalue_customname)="TaskStateAccepted"]; // task has been accepted by an agent.
462	PREPARING = 320 [(gogoproto.enumvalue_customname)="TaskStatePreparing"];
463	READY = 384 [(gogoproto.enumvalue_customname)="TaskStateReady"];
464	STARTING = 448 [(gogoproto.enumvalue_customname)="TaskStateStarting"];
465	RUNNING = 512 [(gogoproto.enumvalue_customname)="TaskStateRunning"];
466	COMPLETE = 576 [(gogoproto.enumvalue_customname)="TaskStateCompleted"]; // successful completion of task (not error code, just ran)
467	SHUTDOWN = 640 [(gogoproto.enumvalue_customname)="TaskStateShutdown"]; // orchestrator requested shutdown
468	FAILED = 704 [(gogoproto.enumvalue_customname)="TaskStateFailed"]; // task execution failed with error
469	// TaskStateRejected means a task never ran, for instance if something about
470	// the environment failed (e.g. setting up a port on that node failed).
471	REJECTED = 768 [(gogoproto.enumvalue_customname)="TaskStateRejected"]; // task could not be executed here.
472	// TaskStateRemove is used to correctly handle service deletions and scale
473	// downs. This allows us to keep track of tasks that have been marked for
474	// deletion, but can't yet be removed because the agent is in the process of
475	// shutting them down. Once the agent has shut down tasks with desired state
476	// REMOVE, the task reaper is responsible for removing them.
477	REMOVE = 800 [(gogoproto.enumvalue_customname)="TaskStateRemove"];
478	// TaskStateOrphaned is used to free up resources associated with service
479	// tasks on unresponsive nodes without having to delete those tasks. This
480	// state is directly assigned to the task by the orchestrator.
481	ORPHANED = 832 [(gogoproto.enumvalue_customname)="TaskStateOrphaned"];
482
483	// NOTE(stevvooe): The state of a task is actually a lamport clock, in that
484	// given two observations, the greater of the two can be considered
485	// correct. To enforce this, we only allow tasks to proceed to a greater
486	// state.
487	//
488	// A byproduct of this design decision is that we must also maintain this
489	// invariant in the protobuf enum values, such that when comparing two
490	// values, the one with the greater value is also the greater state.
491	//
492	// Because we may want to add intervening states a later date, we've left
493	// 64 spaces between each one. This should allow us to make 5 or 6
494	// insertions between each state if we find that we made a mistake and need
495	// another state.
496	//
497	// Remove this message when the states are deemed perfect.
498}
499
500// Container specific status.
501message ContainerStatus {
502	string container_id = 1;
503
504	int32 pid = 2 [(gogoproto.customname) = "PID"];
505	int32 exit_code = 3;
506}
507
508// PortStatus specifies the actual allocated runtime state of a list
509// of port configs.
510message PortStatus {
511	repeated PortConfig ports = 1;
512}
513
514message TaskStatus {
515	// Note: can't use stdtime because this field is nullable.
516	google.protobuf.Timestamp timestamp = 1;
517
518	// State expresses the current state of the task.
519	TaskState state = 2;
520
521	// Message reports a message for the task status. This should provide a
522	// human readable message that can point to how the task actually arrived
523	// at a current state.
524	//
525	// As a convention, we place the a small message here that led to the
526	// current state. For example, if the task is in ready, because it was
527	// prepared, we'd place "prepared" in this field. If we skipped preparation
528	// because the task is prepared, we would put "already prepared" in this
529	// field.
530	string message = 3;
531
532	// Err is set if the task is in an error state, or is unable to
533	// progress from an earlier state because a precondition is
534	// unsatisfied.
535	//
536	// The following states should report a companion error:
537	//
538	//	FAILED, REJECTED
539	//
540	// In general, messages that should be surfaced to users belong in the
541	// Err field, and notes on routine state transitions belong in Message.
542	//
543	// TODO(stevvooe) Integrate this field with the error interface.
544	string err = 4;
545
546	// Container status contains container specific status information.
547	oneof runtime_status {
548		ContainerStatus container = 5;
549	}
550
551	// HostPorts provides a list of ports allocated at the host
552	// level.
553	PortStatus port_status = 6;
554
555	// AppliedBy gives the node ID of the manager that applied this task
556	// status update to the Task object.
557	string applied_by = 7;
558
559	// AppliedAt gives a timestamp of when this status update was applied to
560	// the Task object.
561	// Note: can't use stdtime because this field is nullable.
562	google.protobuf.Timestamp applied_at = 8;
563}
564
565// NetworkAttachmentConfig specifies how a service should be attached to a particular network.
566//
567// For now, this is a simple struct, but this can include future information
568// instructing Swarm on how this service should work on the particular
569// network.
570message NetworkAttachmentConfig {
571	// Target specifies the target network for attachment. This value must be a
572	// network ID.
573	string target = 1;
574	// Aliases specifies a list of discoverable alternate names for the service on this Target.
575	repeated string aliases = 2;
576	// Addresses specifies a list of ipv4 and ipv6 addresses
577	// preferred. If these addresses are not available then the
578	// attachment might fail.
579	repeated string addresses = 3;
580	// DriverAttachmentOpts is a map of driver attachment options for the network target
581	map<string, string> driver_attachment_opts = 4;
582}
583
584// IPAMConfig specifies parameters for IP Address Management.
585message IPAMConfig {
586	// TODO(stevvooe): It may make more sense to manage IPAM and network
587	// definitions separately. This will allow multiple networks to share IPAM
588	// instances. For now, we will follow the conventions of libnetwork and
589	// specify this as part of the network specification.
590
591	// AddressFamily specifies the network address family that
592	// this IPAMConfig belongs to.
593	enum AddressFamily {
594		UNKNOWN = 0; // satisfy proto3
595		IPV4 = 4;
596		IPV6 = 6;
597	}
598
599	AddressFamily family = 1;
600
601	// Subnet defines a network as a CIDR address (ie network and mask
602	// 192.168.0.1/24).
603	string subnet = 2;
604
605	// Range defines the portion of the subnet to allocate to tasks. This is
606	// defined as a subnet within the primary subnet.
607	string range = 3;
608
609	// Gateway address within the subnet.
610	string gateway = 4;
611
612	// Reserved is a list of address from the master pool that should *not* be
613	// allocated. These addresses may have already been allocated or may be
614	// reserved for another allocation manager.
615	map<string, string> reserved = 5;
616}
617
618// PortConfig specifies an exposed port which can be
619// addressed using the given name. This can be later queried
620// using a service discovery api or a DNS SRV query. The node
621// port specifies a port that can be used to address this
622// service external to the cluster by sending a connection
623// request to this port to any node on the cluster.
624message PortConfig {
625	enum Protocol {
626		option (gogoproto.goproto_enum_prefix) = false;
627
628		TCP = 0 [(gogoproto.enumvalue_customname) = "ProtocolTCP"];
629		UDP = 1 [(gogoproto.enumvalue_customname) = "ProtocolUDP"];
630		SCTP = 2 [(gogoproto.enumvalue_customname) = "ProtocolSCTP"];
631	}
632
633	// PublishMode controls how ports are published on the swarm.
634	enum PublishMode {
635		option (gogoproto.enum_customname) = "PublishMode";
636		option (gogoproto.goproto_enum_prefix) = false;
637
638		// PublishModeIngress exposes the port across the cluster on all nodes.
639		INGRESS = 0 [(gogoproto.enumvalue_customname) = "PublishModeIngress"];
640
641		// PublishModeHost exposes the port on just the target host.  If the
642		// published port is undefined, an ephemeral port will be allocated. If
643		// the published port is defined, the node will attempt to allocate it,
644		// erroring the task if it fails.
645		HOST = 1 [(gogoproto.enumvalue_customname) = "PublishModeHost"];
646	}
647
648	// Name for the port. If provided the port information can
649	// be queried using the name as in a DNS SRV query.
650	string name = 1;
651
652	// Protocol for the port which is exposed.
653	Protocol protocol = 2;
654
655	// The port which the application is exposing and is bound to.
656	uint32 target_port = 3;
657
658	// PublishedPort specifies the port on which the service is exposed. If
659	// specified, the port must be within the available range. If not specified
660	// (value is zero), an available port is automatically assigned.
661	uint32 published_port = 4;
662
663	// PublishMode controls how the port is published.
664	PublishMode publish_mode = 5;
665}
666
667// Driver is a generic driver type to be used throughout the API. For now, a
668// driver is simply a name and set of options. The field contents depend on the
669// target use case and driver application. For example, a network driver may
670// have different rules than a volume driver.
671message Driver {
672	string name = 1;
673	map <string, string> options = 2;
674}
675
676message IPAMOptions {
677	Driver driver = 1;
678	repeated IPAMConfig configs = 3;
679}
680
681// Peer should be used anywhere where we are describing a remote peer.
682message Peer {
683	string node_id = 1;
684	string addr = 2;
685}
686
687// WeightedPeer should be used anywhere where we are describing a remote peer
688// with a weight.
689message WeightedPeer {
690	Peer peer = 1;
691	int64 weight = 2;
692}
693
694
695message IssuanceStatus {
696	enum State {
697		option (gogoproto.goproto_enum_prefix) = false;
698
699		UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "IssuanceStateUnknown"];
700		// A new certificate should be issued
701		RENEW = 1 [(gogoproto.enumvalue_customname)="IssuanceStateRenew"];
702		// Certificate is pending acceptance
703		PENDING = 2 [(gogoproto.enumvalue_customname)="IssuanceStatePending"];
704		// successful completion certificate issuance
705		ISSUED = 3 [(gogoproto.enumvalue_customname)="IssuanceStateIssued"];
706		// Certificate issuance failed
707		FAILED = 4 [(gogoproto.enumvalue_customname)="IssuanceStateFailed"];
708		// Signals workers to renew their certificate. From the CA's perspective
709		// this is equivalent to IssuanceStateIssued: a noop.
710		ROTATE = 5 [(gogoproto.enumvalue_customname)="IssuanceStateRotate"];
711	}
712	State state = 1;
713
714	// Err is set if the Certificate Issuance is in an error state.
715	// The following states should report a companion error:
716	//	FAILED
717	string err = 2;
718}
719
720message AcceptancePolicy {
721	message RoleAdmissionPolicy {
722		message Secret {
723			// The actual content (possibly hashed)
724			bytes data = 1;
725			// The type of hash we are using, or "plaintext"
726			string alg = 2;
727		}
728
729		NodeRole role = 1;
730		// Autoaccept controls which roles' certificates are automatically
731		// issued without administrator intervention.
732		bool autoaccept = 2;
733		// Secret represents a user-provided string that is necessary for new
734		// nodes to join the cluster
735		Secret secret = 3;
736	}
737
738	repeated RoleAdmissionPolicy policies = 1;
739}
740
741message ExternalCA {
742	enum CAProtocol {
743		CFSSL = 0 [(gogoproto.enumvalue_customname) = "CAProtocolCFSSL"];
744	}
745
746	// Protocol is the protocol used by this external CA.
747	CAProtocol protocol = 1;
748
749	// URL is the URL where the external CA can be reached.
750	string url = 2 [(gogoproto.customname) = "URL"];
751
752	// Options is a set of additional key/value pairs whose interpretation
753	// depends on the specified CA type.
754	map<string, string> options = 3;
755
756	// CACert specifies which root CA is used by this external CA
757	bytes ca_cert = 4 [(gogoproto.customname) = "CACert"];
758}
759
760message CAConfig {
761	// NodeCertExpiry is the duration certificates should be issued for
762	// Note: can't use stdduration because this field needs to be nullable.
763	google.protobuf.Duration node_cert_expiry = 1;
764
765	// ExternalCAs is a list of CAs to which a manager node will make
766	// certificate signing requests for node certificates.
767	repeated ExternalCA external_cas = 2 [(gogoproto.customname) = "ExternalCAs"];
768
769	// SigningCACert is the desired CA certificate to be used as the root and
770	// signing CA for the swarm.  If not provided, indicates that we are either happy
771	// with the current configuration, or (together with a bump in the ForceRotate value)
772	// that we want a certificate and key generated for us.
773	bytes signing_ca_cert = 3 [(gogoproto.customname) = "SigningCACert"];
774
775	// SigningCAKey is the desired private key, matching the signing CA cert, to be used
776	// to sign certificates for the swarm
777	bytes signing_ca_key = 4 [(gogoproto.customname) = "SigningCAKey"];
778
779	// ForceRotate is a counter that triggers a root CA rotation even if no relevant
780	// parameters have been in the spec. This will force the manager to generate a new
781	// certificate and key, if none have been provided.
782	uint64 force_rotate = 5;
783}
784
785// OrchestrationConfig defines cluster-level orchestration settings.
786message OrchestrationConfig {
787	// TaskHistoryRetentionLimit is the number of historic tasks to keep per instance or
788	// node. If negative, never remove completed or failed tasks.
789	int64 task_history_retention_limit = 1;
790
791}
792
793// TaskDefaults specifies default values for task creation.
794message TaskDefaults {
795	// LogDriver specifies the log driver to use for the cluster if not
796	// specified for each task.
797	//
798	// If this is changed, only new tasks will pick up the new log driver.
799	// Existing tasks will continue to use the previous default until rescheduled.
800	Driver log_driver = 1;
801}
802
803// DispatcherConfig defines cluster-level dispatcher settings.
804message DispatcherConfig {
805	// HeartbeatPeriod defines how often agent should send heartbeats to
806	// dispatcher.
807	// Note: can't use stdduration because this field needs to be nullable.
808	google.protobuf.Duration heartbeat_period = 1;
809}
810
811// RaftConfig defines raft settings for the cluster.
812message RaftConfig {
813	// SnapshotInterval is the number of log entries between snapshots.
814	uint64 snapshot_interval = 1;
815	// KeepOldSnapshots is the number of snapshots to keep beyond the
816	// current snapshot.
817	uint64 keep_old_snapshots = 2;
818	// LogEntriesForSlowFollowers is the number of log entries to keep
819	// around to sync up slow followers after a snapshot is created.
820	uint64 log_entries_for_slow_followers = 3;
821	// HeartbeatTick defines the amount of ticks (in seconds) between
822	// each heartbeat message sent to other members for health-check.
823	uint32 heartbeat_tick = 4;
824	// ElectionTick defines the amount of ticks (in seconds) needed
825	// without a leader to trigger a new election.
826	uint32 election_tick = 5;
827}
828
829message EncryptionConfig {
830	// AutoLockManagers specifies whether or not managers TLS keys and raft data
831	// should be encrypted at rest in such a way that they must be unlocked
832	// before the manager node starts up again.
833	bool auto_lock_managers = 1;
834}
835
836message SpreadOver {
837	string spread_descriptor = 1; // label descriptor, such as engine.labels.az
838	// TODO: support node information beyond engine and node labels
839
840	// TODO: in the future, add a map that provides weights for weighted
841	// spreading.
842}
843
844message PlacementPreference {
845	oneof Preference {
846		SpreadOver spread = 1;
847	}
848}
849
850// Placement specifies task distribution constraints.
851message Placement {
852	// Constraints specifies a set of requirements a node should meet for a task.
853	repeated string constraints = 1;
854
855	// Preferences provide a way to make the scheduler aware of factors
856	// such as topology. They are provided in order from highest to lowest
857	// precedence.
858	repeated PlacementPreference preferences = 2;
859
860	// Platforms stores all the platforms that the image can run on.
861	// This field is used in the platform filter for scheduling. If empty,
862	// then the platform filter is off, meaning there are no scheduling restrictions.
863	repeated Platform platforms = 3;
864}
865
866// JoinToken contains the join tokens for workers and managers.
867message JoinTokens {
868	// Worker is the join token workers may use to join the swarm.
869	string worker = 1;
870
871	// Manager is the join token workers may use to join the swarm.
872	string manager = 2;
873}
874
875message RootCA {
876	// CAKey is the root CA private key.
877	bytes ca_key = 1 [(gogoproto.customname) = "CAKey"];
878
879	// CACert is the root CA certificate.
880	bytes ca_cert = 2 [(gogoproto.customname) = "CACert"];
881
882	// CACertHash is the digest of the CA Certificate.
883	string ca_cert_hash = 3 [(gogoproto.customname) = "CACertHash"];
884
885	// JoinTokens contains the join tokens for workers and managers.
886	JoinTokens join_tokens = 4 [(gogoproto.nullable) = false];
887
888	// RootRotation contains the new root cert and key we want to rotate to - if this is nil, we are not in the
889	// middle of a root rotation
890	RootRotation root_rotation = 5;
891
892	// LastForcedRotation matches the Cluster Spec's CAConfig's ForceRotation counter.
893	// It indicates when the current CA cert and key were generated (or updated).
894	uint64 last_forced_rotation = 6;
895}
896
897
898enum NodeRole {
899	option (gogoproto.enum_customname) = "NodeRole";
900	option (gogoproto.goproto_enum_prefix) = false;
901
902	WORKER = 0 [(gogoproto.enumvalue_customname) = "NodeRoleWorker"];
903	MANAGER = 1 [(gogoproto.enumvalue_customname) = "NodeRoleManager"];
904}
905
906message Certificate {
907	NodeRole role = 1;
908
909	bytes csr = 2 [(gogoproto.customname) = "CSR"];
910
911	IssuanceStatus status = 3 [(gogoproto.nullable) = false];
912
913	bytes certificate = 4;
914
915	// CN represents the node ID.
916	string cn = 5 [(gogoproto.customname) = "CN"];
917}
918
919
920// Symmetric keys to encrypt inter-agent communication.
921message EncryptionKey {
922	// Agent subsystem the key is intended for. Example:
923	// networking:gossip
924	string subsystem = 1;
925
926	// Encryption algorithm that can implemented using this key
927	enum Algorithm {
928		option (gogoproto.goproto_enum_prefix) = false;
929
930		AES_128_GCM = 0;
931	}
932
933	Algorithm algorithm = 2;
934
935	bytes key = 3;
936
937	// Time stamp from the lamport clock of the key allocator to
938	// identify the relative age of the key.
939	uint64 lamport_time = 4;
940}
941
942// ManagerStatus provides informations about the state of a manager in the cluster.
943message ManagerStatus {
944	// RaftID specifies the internal ID used by the manager in a raft context, it can never be modified
945	// and is used only for information purposes
946	uint64 raft_id = 1;
947
948	// Addr is the address advertised to raft.
949	string addr = 2;
950
951	// Leader is set to true if this node is the raft leader.
952	bool leader = 3;
953
954	// Reachability specifies whether this node is reachable.
955	RaftMemberStatus.Reachability reachability = 4;
956}
957
958// FileTarget represents a specific target that is backed by a file
959message FileTarget {
960	// Name represents the final filename in the filesystem
961	string name = 1;
962
963	// UID represents the file UID
964	string uid = 2 [(gogoproto.customname) = "UID"];
965
966	// GID represents the file GID
967	string gid = 3 [(gogoproto.customname) = "GID"];
968
969	// Mode represents the FileMode of the file
970	uint32 mode = 4 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false];
971}
972
973// SecretReference is the linkage between a service and a secret that it uses.
974message SecretReference {
975	// SecretID represents the ID of the specific Secret that we're
976	// referencing. This identifier exists so that SecretReferences don't leak
977	// any information about the secret contents.
978	string secret_id = 1;
979
980	// SecretName is the name of the secret that this references, but this is just provided for
981	// lookup/display purposes.  The secret in the reference will be identified by its ID.
982	string secret_name = 2;
983
984	// Target specifies how this secret should be exposed to the task.
985	oneof target {
986		FileTarget file = 3;
987	}
988}
989
990// ConfigReference is the linkage between a service and a config that it uses.
991message ConfigReference {
992	// ConfigID represents the ID of the specific Config that we're
993	// referencing.
994	string config_id = 1;
995
996	// ConfigName is the name of the config that this references, but this is just provided for
997	// lookup/display purposes. The config in the reference will be identified by its ID.
998	string config_name = 2;
999
1000	// Target specifies how this secret should be exposed to the task.
1001	oneof target {
1002		FileTarget file = 3;
1003	}
1004}
1005
1006// BlacklistedCertificate is a record for a blacklisted certificate. It does not
1007// contain the certificate's CN, because these records are indexed by CN.
1008message BlacklistedCertificate {
1009	// Expiry is the latest known expiration time of a certificate that
1010	// was issued for the given CN.
1011	// Note: can't use stdtime because this field is nullable.
1012	google.protobuf.Timestamp expiry = 1;
1013}
1014
1015// HealthConfig holds configuration settings for the HEALTHCHECK feature.
1016message HealthConfig {
1017	// Test is the test to perform to check that the container is healthy.
1018	// An empty slice means to inherit the default.
1019	// The options are:
1020	// {} : inherit healthcheck
1021	// {"NONE"} : disable healthcheck
1022	// {"CMD", args...} : exec arguments directly
1023	// {"CMD-SHELL", command} : run command with system's default shell
1024	repeated string test = 1;
1025
1026	// Interval is the time to wait between checks. Zero means inherit.
1027	// Note: can't use stdduration because this field needs to be nullable.
1028	google.protobuf.Duration interval = 2;
1029
1030	// Timeout is the time to wait before considering the check to have hung.
1031	// Zero means inherit.
1032	// Note: can't use stdduration because this field needs to be nullable.
1033	google.protobuf.Duration timeout = 3;
1034
1035	// Retries is the number of consecutive failures needed to consider a
1036	// container as unhealthy. Zero means inherit.
1037	int32 retries = 4;
1038
1039	// Start period is the period for container initialization during
1040	// which health check failures will note count towards the maximum
1041	// number of retries.
1042	google.protobuf.Duration start_period = 5;
1043}
1044
1045message MaybeEncryptedRecord {
1046	enum Algorithm {
1047		NONE = 0 [(gogoproto.enumvalue_customname) = "NotEncrypted"];
1048		SECRETBOX_SALSA20_POLY1305 = 1 [(gogoproto.enumvalue_customname) = "NACLSecretboxSalsa20Poly1305"];
1049		FERNET_AES_128_CBC = 2 [(gogoproto.enumvalue_customname) = "FernetAES128CBC"];
1050	}
1051
1052	Algorithm algorithm = 1;
1053	bytes data = 2;
1054	bytes nonce = 3;
1055}
1056
1057
1058message RootRotation {
1059	bytes ca_cert = 1 [(gogoproto.customname) = "CACert"];
1060	bytes ca_key = 2 [(gogoproto.customname) = "CAKey"];
1061	// cross-signed CA cert is the CACert that has been cross-signed by the previous root
1062	bytes cross_signed_ca_cert = 3 [(gogoproto.customname) = "CrossSignedCACert"];
1063}
1064
1065// Privileges specifies security configuration/permissions.
1066message Privileges {
1067	// CredentialSpec for managed service account (Windows only).
1068	message CredentialSpec {
1069		oneof source {
1070			string file = 1;
1071			string registry = 2;
1072		}
1073	}
1074	CredentialSpec credential_spec = 1;
1075
1076	// SELinuxContext contains the SELinux labels for the container.
1077	message SELinuxContext {
1078		bool disable = 1;
1079
1080		string user = 2;
1081		string role = 3;
1082		string type = 4;
1083		string level = 5;
1084	}
1085	SELinuxContext selinux_context = 2 [(gogoproto.customname) = "SELinuxContext"];
1086}
1087