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