Browse code

Re-vendor docker/swarmkit to d2e48a332063ccd4ea26b6262ee717de997de560

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>

Andrea Luzzardi authored on 2017/04/04 12:54:30
Showing 45 changed files
... ...
@@ -97,7 +97,7 @@ func secretReferencesToGRPC(sr []*types.SecretReference) []*swarmapi.SecretRefer
97 97
 		}
98 98
 		if s.File != nil {
99 99
 			ref.Target = &swarmapi.SecretReference_File{
100
-				File: &swarmapi.SecretReference_FileTarget{
100
+				File: &swarmapi.FileTarget{
101 101
 					Name: s.File.Name,
102 102
 					UID:  s.File.UID,
103 103
 					GID:  s.File.GID,
... ...
@@ -105,7 +105,7 @@ github.com/docker/containerd 9048e5e50717ea4497b757314bad98ea3763c145
105 105
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
106 106
 
107 107
 # cluster
108
-github.com/docker/swarmkit b74ec2b81bb1d4a998f461bb2dc59b9408b7790f
108
+github.com/docker/swarmkit d2e48a332063ccd4ea26b6262ee717de997de560
109 109
 github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
110 110
 github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2
111 111
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
... ...
@@ -1,6 +1,7 @@
1 1
 package agent
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"fmt"
5 6
 	"math/rand"
6 7
 	"reflect"
... ...
@@ -44,6 +45,8 @@ type Agent struct {
44 44
 	stopOnce  sync.Once     // only allow stop to be called once
45 45
 	closed    chan struct{} // only closed in run
46 46
 	err       error         // read only after closed is closed
47
+
48
+	nodeUpdatePeriod time.Duration
47 49
 }
48 50
 
49 51
 // New returns a new agent, ready for task dispatch.
... ...
@@ -53,14 +56,15 @@ func New(config *Config) (*Agent, error) {
53 53
 	}
54 54
 
55 55
 	a := &Agent{
56
-		config:   config,
57
-		sessionq: make(chan sessionOperation),
58
-		started:  make(chan struct{}),
59
-		leaving:  make(chan struct{}),
60
-		left:     make(chan struct{}),
61
-		stopped:  make(chan struct{}),
62
-		closed:   make(chan struct{}),
63
-		ready:    make(chan struct{}),
56
+		config:           config,
57
+		sessionq:         make(chan sessionOperation),
58
+		started:          make(chan struct{}),
59
+		leaving:          make(chan struct{}),
60
+		left:             make(chan struct{}),
61
+		stopped:          make(chan struct{}),
62
+		closed:           make(chan struct{}),
63
+		ready:            make(chan struct{}),
64
+		nodeUpdatePeriod: nodeUpdatePeriod,
64 65
 	}
65 66
 
66 67
 	a.worker = newWorker(config.DB, config.Executor, a)
... ...
@@ -182,13 +186,15 @@ func (a *Agent) run(ctx context.Context) {
182 182
 	log.G(ctx).Debug("(*Agent).run")
183 183
 	defer log.G(ctx).Debug("(*Agent).run exited")
184 184
 
185
+	nodeTLSInfo := a.config.NodeTLSInfo
186
+
185 187
 	// get the node description
186
-	nodeDescription, err := a.nodeDescriptionWithHostname(ctx)
188
+	nodeDescription, err := a.nodeDescriptionWithHostname(ctx, nodeTLSInfo)
187 189
 	if err != nil {
188 190
 		log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: node description unavailable")
189 191
 	}
190 192
 	// nodeUpdateTicker is used to periodically check for updates to node description
191
-	nodeUpdateTicker := time.NewTicker(nodeUpdatePeriod)
193
+	nodeUpdateTicker := time.NewTicker(a.nodeUpdatePeriod)
192 194
 	defer nodeUpdateTicker.Stop()
193 195
 
194 196
 	var (
... ...
@@ -214,6 +220,35 @@ func (a *Agent) run(ctx context.Context) {
214 214
 
215 215
 	a.worker.Listen(ctx, reporter)
216 216
 
217
+	updateNode := func() {
218
+		// skip updating if the registration isn't finished
219
+		if registered != nil {
220
+			return
221
+		}
222
+		// get the current node description
223
+		newNodeDescription, err := a.nodeDescriptionWithHostname(ctx, nodeTLSInfo)
224
+		if err != nil {
225
+			log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: updated node description unavailable")
226
+		}
227
+
228
+		// if newNodeDescription is nil, it will cause a panic when
229
+		// trying to create a session. Typically this can happen
230
+		// if the engine goes down
231
+		if newNodeDescription == nil {
232
+			return
233
+		}
234
+
235
+		// if the node description has changed, update it to the new one
236
+		// and close the session. The old session will be stopped and a
237
+		// new one will be created with the updated description
238
+		if !reflect.DeepEqual(nodeDescription, newNodeDescription) {
239
+			nodeDescription = newNodeDescription
240
+			// close the session
241
+			log.G(ctx).Info("agent: found node update")
242
+			session.sendError(nil)
243
+		}
244
+	}
245
+
217 246
 	for {
218 247
 		select {
219 248
 		case operation := <-sessionq:
... ...
@@ -237,7 +272,8 @@ func (a *Agent) run(ctx context.Context) {
237 237
 
238 238
 			switch msg.Type {
239 239
 			case api.AssignmentsMessage_COMPLETE:
240
-				// Need to assign secrets before tasks, because tasks might depend on new secrets
240
+				// Need to assign secrets and configs before tasks,
241
+				// because tasks might depend on new secrets or configs
241 242
 				if err := a.worker.Assign(ctx, msg.Changes); err != nil {
242 243
 					log.G(ctx).WithError(err).Error("failed to synchronize worker assignments")
243 244
 				}
... ...
@@ -247,7 +283,7 @@ func (a *Agent) run(ctx context.Context) {
247 247
 				}
248 248
 			}
249 249
 		case msg := <-session.messages:
250
-			if err := a.handleSessionMessage(ctx, msg); err != nil {
250
+			if err := a.handleSessionMessage(ctx, msg, nodeTLSInfo); err != nil {
251 251
 				log.G(ctx).WithError(err).Error("session message handler failed")
252 252
 			}
253 253
 		case sub := <-session.subscriptions:
... ...
@@ -305,33 +341,17 @@ func (a *Agent) run(ctx context.Context) {
305 305
 			}
306 306
 			session = newSession(ctx, a, delay, session.sessionID, nodeDescription)
307 307
 			registered = session.registered
308
-		case <-nodeUpdateTicker.C:
309
-			// skip this case if the registration isn't finished
310
-			if registered != nil {
311
-				continue
312
-			}
313
-			// get the current node description
314
-			newNodeDescription, err := a.nodeDescriptionWithHostname(ctx)
315
-			if err != nil {
316
-				log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: updated node description unavailable")
317
-			}
318
-
319
-			// if newNodeDescription is nil, it will cause a panic when
320
-			// trying to create a session. Typically this can happen
321
-			// if the engine goes down
322
-			if newNodeDescription == nil {
323
-				continue
324
-			}
325
-
326
-			// if the node description has changed, update it to the new one
327
-			// and close the session. The old session will be stopped and a
328
-			// new one will be created with the updated description
329
-			if !reflect.DeepEqual(nodeDescription, newNodeDescription) {
330
-				nodeDescription = newNodeDescription
331
-				// close the session
332
-				log.G(ctx).Info("agent: found node update")
333
-				session.sendError(nil)
308
+		case ev := <-a.config.NotifyTLSChange:
309
+			// the TLS info has changed, so force a check to see if we need to restart the session
310
+			if tlsInfo, ok := ev.(*api.NodeTLSInfo); ok {
311
+				nodeTLSInfo = tlsInfo
312
+				updateNode()
313
+				nodeUpdateTicker.Stop()
314
+				nodeUpdateTicker = time.NewTicker(a.nodeUpdatePeriod)
334 315
 			}
316
+		case <-nodeUpdateTicker.C:
317
+			// periodically check to see whether the node information has changed, and if so, restart the session
318
+			updateNode()
335 319
 		case <-a.stopped:
336 320
 			// TODO(stevvooe): Wait on shutdown and cleanup. May need to pump
337 321
 			// this loop a few times.
... ...
@@ -347,7 +367,7 @@ func (a *Agent) run(ctx context.Context) {
347 347
 	}
348 348
 }
349 349
 
350
-func (a *Agent) handleSessionMessage(ctx context.Context, message *api.SessionMessage) error {
350
+func (a *Agent) handleSessionMessage(ctx context.Context, message *api.SessionMessage, nti *api.NodeTLSInfo) error {
351 351
 	seen := map[api.Peer]struct{}{}
352 352
 	for _, manager := range message.Managers {
353 353
 		if manager.Peer.Addr == "" {
... ...
@@ -358,18 +378,28 @@ func (a *Agent) handleSessionMessage(ctx context.Context, message *api.SessionMe
358 358
 		seen[*manager.Peer] = struct{}{}
359 359
 	}
360 360
 
361
-	if message.Node != nil {
362
-		if a.node == nil || !nodesEqual(a.node, message.Node) {
363
-			if a.config.NotifyNodeChange != nil {
364
-				a.config.NotifyNodeChange <- message.Node.Copy()
365
-			}
366
-			a.node = message.Node.Copy()
367
-			if err := a.config.Executor.Configure(ctx, a.node); err != nil {
368
-				log.G(ctx).WithError(err).Error("node configure failed")
369
-			}
361
+	var changes *NodeChanges
362
+	if message.Node != nil && (a.node == nil || !nodesEqual(a.node, message.Node)) {
363
+		if a.config.NotifyNodeChange != nil {
364
+			changes = &NodeChanges{Node: message.Node.Copy()}
365
+		}
366
+		a.node = message.Node.Copy()
367
+		if err := a.config.Executor.Configure(ctx, a.node); err != nil {
368
+			log.G(ctx).WithError(err).Error("node configure failed")
369
+		}
370
+	}
371
+	if len(message.RootCA) > 0 && !bytes.Equal(message.RootCA, nti.TrustRoot) {
372
+		if changes == nil {
373
+			changes = &NodeChanges{RootCert: message.RootCA}
374
+		} else {
375
+			changes.RootCert = message.RootCA
370 376
 		}
371 377
 	}
372 378
 
379
+	if changes != nil {
380
+		a.config.NotifyNodeChange <- changes
381
+	}
382
+
373 383
 	// prune managers not in list.
374 384
 	for peer := range a.config.ConnBroker.Remotes().Weights() {
375 385
 		if _, ok := seen[peer]; !ok {
... ...
@@ -517,12 +547,15 @@ func (a *Agent) Publisher(ctx context.Context, subscriptionID string) (exec.LogP
517 517
 }
518 518
 
519 519
 // nodeDescriptionWithHostname retrieves node description, and overrides hostname if available
520
-func (a *Agent) nodeDescriptionWithHostname(ctx context.Context) (*api.NodeDescription, error) {
520
+func (a *Agent) nodeDescriptionWithHostname(ctx context.Context, tlsInfo *api.NodeTLSInfo) (*api.NodeDescription, error) {
521 521
 	desc, err := a.config.Executor.Describe(ctx)
522 522
 
523
-	// Override hostname
524
-	if a.config.Hostname != "" && desc != nil {
525
-		desc.Hostname = a.config.Hostname
523
+	// Override hostname and TLS info
524
+	if desc != nil {
525
+		if a.config.Hostname != "" && desc != nil {
526
+			desc.Hostname = a.config.Hostname
527
+		}
528
+		desc.TLSInfo = tlsInfo
526 529
 	}
527 530
 	return desc, err
528 531
 }
... ...
@@ -2,6 +2,7 @@ package agent
2 2
 
3 3
 import (
4 4
 	"github.com/boltdb/bolt"
5
+	"github.com/docker/go-events"
5 6
 	"github.com/docker/swarmkit/agent/exec"
6 7
 	"github.com/docker/swarmkit/api"
7 8
 	"github.com/docker/swarmkit/connectionbroker"
... ...
@@ -9,6 +10,13 @@ import (
9 9
 	"google.golang.org/grpc/credentials"
10 10
 )
11 11
 
12
+// NodeChanges encapsulates changes that should be made to the node as per session messages
13
+// from the dispatcher
14
+type NodeChanges struct {
15
+	Node     *api.Node
16
+	RootCert []byte
17
+}
18
+
12 19
 // Config provides values for an Agent.
13 20
 type Config struct {
14 21
 	// Hostname the name of host for agent instance.
... ...
@@ -25,10 +33,16 @@ type Config struct {
25 25
 	DB *bolt.DB
26 26
 
27 27
 	// NotifyNodeChange channel receives new node changes from session messages.
28
-	NotifyNodeChange chan<- *api.Node
28
+	NotifyNodeChange chan<- *NodeChanges
29
+
30
+	// NotifyTLSChange channel sends new TLS information changes, which can cause a session to restart
31
+	NotifyTLSChange <-chan events.Event
29 32
 
30 33
 	// Credentials is credentials for grpc connection to manager.
31 34
 	Credentials credentials.TransportCredentials
35
+
36
+	// NodeTLSInfo contains the starting node TLS info to bootstrap into the agent
37
+	NodeTLSInfo *api.NodeTLSInfo
32 38
 }
33 39
 
34 40
 func (c *Config) validate() error {
... ...
@@ -44,5 +58,9 @@ func (c *Config) validate() error {
44 44
 		return errors.New("agent: database required")
45 45
 	}
46 46
 
47
+	if c.NodeTLSInfo == nil {
48
+		return errors.New("agent: Node TLS info is required")
49
+	}
50
+
47 51
 	return nil
48 52
 }
49 53
new file mode 100644
... ...
@@ -0,0 +1,87 @@
0
+package configs
1
+
2
+import (
3
+	"sync"
4
+
5
+	"github.com/docker/swarmkit/agent/exec"
6
+	"github.com/docker/swarmkit/api"
7
+)
8
+
9
+// configs is a map that keeps all the currently available configs to the agent
10
+// mapped by config ID.
11
+type configs struct {
12
+	mu sync.RWMutex
13
+	m  map[string]*api.Config
14
+}
15
+
16
+// NewManager returns a place to store configs.
17
+func NewManager() exec.ConfigsManager {
18
+	return &configs{
19
+		m: make(map[string]*api.Config),
20
+	}
21
+}
22
+
23
+// Get returns a config by ID.  If the config doesn't exist, returns nil.
24
+func (r *configs) Get(configID string) *api.Config {
25
+	r.mu.RLock()
26
+	defer r.mu.RUnlock()
27
+	if r, ok := r.m[configID]; ok {
28
+		return r
29
+	}
30
+	return nil
31
+}
32
+
33
+// Add adds one or more configs to the config map.
34
+func (r *configs) Add(configs ...api.Config) {
35
+	r.mu.Lock()
36
+	defer r.mu.Unlock()
37
+	for _, config := range configs {
38
+		r.m[config.ID] = config.Copy()
39
+	}
40
+}
41
+
42
+// Remove removes one or more configs by ID from the config map. Succeeds
43
+// whether or not the given IDs are in the map.
44
+func (r *configs) Remove(configs []string) {
45
+	r.mu.Lock()
46
+	defer r.mu.Unlock()
47
+	for _, config := range configs {
48
+		delete(r.m, config)
49
+	}
50
+}
51
+
52
+// Reset removes all the configs.
53
+func (r *configs) Reset() {
54
+	r.mu.Lock()
55
+	defer r.mu.Unlock()
56
+	r.m = make(map[string]*api.Config)
57
+}
58
+
59
+// taskRestrictedConfigsProvider restricts the ids to the task.
60
+type taskRestrictedConfigsProvider struct {
61
+	configs   exec.ConfigGetter
62
+	configIDs map[string]struct{} // allow list of config ids
63
+}
64
+
65
+func (sp *taskRestrictedConfigsProvider) Get(configID string) *api.Config {
66
+	if _, ok := sp.configIDs[configID]; !ok {
67
+		return nil
68
+	}
69
+
70
+	return sp.configs.Get(configID)
71
+}
72
+
73
+// Restrict provides a getter that only allows access to the configs
74
+// referenced by the task.
75
+func Restrict(configs exec.ConfigGetter, t *api.Task) exec.ConfigGetter {
76
+	cids := map[string]struct{}{}
77
+
78
+	container := t.Spec.GetContainer()
79
+	if container != nil {
80
+		for _, configRef := range container.Configs {
81
+			cids[configRef.ConfigID] = struct{}{}
82
+		}
83
+	}
84
+
85
+	return &taskRestrictedConfigsProvider{configs: configs, configIDs: cids}
86
+}
0 87
new file mode 100644
... ...
@@ -0,0 +1,52 @@
0
+package agent
1
+
2
+import (
3
+	"github.com/docker/swarmkit/agent/configs"
4
+	"github.com/docker/swarmkit/agent/exec"
5
+	"github.com/docker/swarmkit/agent/secrets"
6
+	"github.com/docker/swarmkit/api"
7
+)
8
+
9
+type dependencyManager struct {
10
+	secrets exec.SecretsManager
11
+	configs exec.ConfigsManager
12
+}
13
+
14
+// NewDependencyManager creates a dependency manager object that wraps
15
+// objects which provide access to various dependency types.
16
+func NewDependencyManager() exec.DependencyManager {
17
+	return &dependencyManager{
18
+		secrets: secrets.NewManager(),
19
+		configs: configs.NewManager(),
20
+	}
21
+}
22
+
23
+func (d *dependencyManager) Secrets() exec.SecretsManager {
24
+	return d.secrets
25
+}
26
+
27
+func (d *dependencyManager) Configs() exec.ConfigsManager {
28
+	return d.configs
29
+}
30
+
31
+type dependencyGetter struct {
32
+	secrets exec.SecretGetter
33
+	configs exec.ConfigGetter
34
+}
35
+
36
+func (d *dependencyGetter) Secrets() exec.SecretGetter {
37
+	return d.secrets
38
+}
39
+
40
+func (d *dependencyGetter) Configs() exec.ConfigGetter {
41
+	return d.configs
42
+}
43
+
44
+// Restrict provides getters that only allows access to the dependencies
45
+// referenced by the task.
46
+func Restrict(dependencies exec.DependencyManager, t *api.Task) exec.DependencyGetter {
47
+	return &dependencyGetter{
48
+		secrets: secrets.Restrict(dependencies.Secrets(), t),
49
+		configs: configs.Restrict(dependencies.Configs(), t),
50
+	}
51
+}
... ...
@@ -28,6 +28,26 @@ type SecretsProvider interface {
28 28
 	Secrets() SecretsManager
29 29
 }
30 30
 
31
+// ConfigsProvider is implemented by objects that can store configs,
32
+// typically an executor.
33
+type ConfigsProvider interface {
34
+	Configs() ConfigsManager
35
+}
36
+
37
+// DependencyManager is a meta-object that can keep track of typed objects
38
+// such as secrets and configs.
39
+type DependencyManager interface {
40
+	SecretsProvider
41
+	ConfigsProvider
42
+}
43
+
44
+// DependencyGetter is a meta-object that can provide access to typed objects
45
+// such as secrets and configs.
46
+type DependencyGetter interface {
47
+	Secrets() SecretGetter
48
+	Configs() ConfigGetter
49
+}
50
+
31 51
 // SecretGetter contains secret data necessary for the Controller.
32 52
 type SecretGetter interface {
33 53
 	// Get returns the the secret with a specific secret ID, if available.
... ...
@@ -43,3 +63,19 @@ type SecretsManager interface {
43 43
 	Remove(secrets []string)   // remove the secrets by ID
44 44
 	Reset()                    // remove all secrets
45 45
 }
46
+
47
+// ConfigGetter contains config data necessary for the Controller.
48
+type ConfigGetter interface {
49
+	// Get returns the the config with a specific config ID, if available.
50
+	// When the config is not available, the return will be nil.
51
+	Get(configID string) *api.Config
52
+}
53
+
54
+// ConfigsManager is the interface for config storage and updates.
55
+type ConfigsManager interface {
56
+	ConfigGetter
57
+
58
+	Add(configs ...api.Config) // add one or more configs
59
+	Remove(configs []string)   // remove the configs by ID
60
+	Reset()                    // remove all configs
61
+}
... ...
@@ -23,12 +23,13 @@ type Worker interface {
23 23
 	// It is not safe to call any worker function after that.
24 24
 	Close()
25 25
 
26
-	// Assign assigns a complete set of tasks and secrets to a worker. Any task or secrets not included in
27
-	// this set will be removed.
26
+	// Assign assigns a complete set of tasks and configs/secrets to a
27
+	// worker. Any items not included in this set will be removed.
28 28
 	Assign(ctx context.Context, assignments []*api.AssignmentChange) error
29 29
 
30
-	// Updates updates an incremental set of tasks or secrets of the worker. Any task/secret not included
31
-	// either in added or removed will remain untouched.
30
+	// Updates updates an incremental set of tasks or configs/secrets of
31
+	// the worker. Any items not included either in added or removed will
32
+	// remain untouched.
32 33
 	Update(ctx context.Context, assignments []*api.AssignmentChange) error
33 34
 
34 35
 	// Listen to updates about tasks controlled by the worker. When first
... ...
@@ -119,11 +120,11 @@ func (w *worker) Close() {
119 119
 	w.taskevents.Close()
120 120
 }
121 121
 
122
-// Assign assigns a full set of tasks and secrets to the worker.
122
+// Assign assigns a full set of tasks, configs, and secrets to the worker.
123 123
 // Any tasks not previously known will be started. Any tasks that are in the task set
124 124
 // and already running will be updated, if possible. Any tasks currently running on
125 125
 // the worker outside the task set will be terminated.
126
-// Any secrets not in the set of assignments will be removed.
126
+// Anything not in the set of assignments will be removed.
127 127
 func (w *worker) Assign(ctx context.Context, assignments []*api.AssignmentChange) error {
128 128
 	w.mu.Lock()
129 129
 	defer w.mu.Unlock()
... ...
@@ -136,20 +137,28 @@ func (w *worker) Assign(ctx context.Context, assignments []*api.AssignmentChange
136 136
 		"len(assignments)": len(assignments),
137 137
 	}).Debug("(*worker).Assign")
138 138
 
139
-	// Need to update secrets before tasks, because tasks might depend on new secrets
139
+	// Need to update dependencies before tasks
140
+
140 141
 	err := reconcileSecrets(ctx, w, assignments, true)
141 142
 	if err != nil {
142 143
 		return err
143 144
 	}
144 145
 
146
+	err = reconcileConfigs(ctx, w, assignments, true)
147
+	if err != nil {
148
+		return err
149
+	}
150
+
145 151
 	return reconcileTaskState(ctx, w, assignments, true)
146 152
 }
147 153
 
148
-// Update updates the set of tasks and secret for the worker.
154
+// Update updates the set of tasks, configs, and secrets for the worker.
149 155
 // Tasks in the added set will be added to the worker, and tasks in the removed set
150 156
 // will be removed from the worker
151 157
 // Secrets in the added set will be added to the worker, and secrets in the removed set
152 158
 // will be removed from the worker.
159
+// Configs in the added set will be added to the worker, and configs in the removed set
160
+// will be removed from the worker.
153 161
 func (w *worker) Update(ctx context.Context, assignments []*api.AssignmentChange) error {
154 162
 	w.mu.Lock()
155 163
 	defer w.mu.Unlock()
... ...
@@ -167,6 +176,11 @@ func (w *worker) Update(ctx context.Context, assignments []*api.AssignmentChange
167 167
 		return err
168 168
 	}
169 169
 
170
+	err = reconcileConfigs(ctx, w, assignments, false)
171
+	if err != nil {
172
+		return err
173
+	}
174
+
170 175
 	return reconcileTaskState(ctx, w, assignments, false)
171 176
 }
172 177
 
... ...
@@ -318,7 +332,7 @@ func reconcileSecrets(ctx context.Context, w *worker, assignments []*api.Assignm
318 318
 		}
319 319
 	}
320 320
 
321
-	provider, ok := w.executor.(exec.SecretsProvider)
321
+	secretsProvider, ok := w.executor.(exec.SecretsProvider)
322 322
 	if !ok {
323 323
 		if len(updatedSecrets) != 0 || len(removedSecrets) != 0 {
324 324
 			log.G(ctx).Warn("secrets update ignored; executor does not support secrets")
... ...
@@ -326,7 +340,7 @@ func reconcileSecrets(ctx context.Context, w *worker, assignments []*api.Assignm
326 326
 		return nil
327 327
 	}
328 328
 
329
-	secrets := provider.Secrets()
329
+	secrets := secretsProvider.Secrets()
330 330
 
331 331
 	log.G(ctx).WithFields(logrus.Fields{
332 332
 		"len(updatedSecrets)": len(updatedSecrets),
... ...
@@ -344,6 +358,49 @@ func reconcileSecrets(ctx context.Context, w *worker, assignments []*api.Assignm
344 344
 	return nil
345 345
 }
346 346
 
347
+func reconcileConfigs(ctx context.Context, w *worker, assignments []*api.AssignmentChange, fullSnapshot bool) error {
348
+	var (
349
+		updatedConfigs []api.Config
350
+		removedConfigs []string
351
+	)
352
+	for _, a := range assignments {
353
+		if r := a.Assignment.GetConfig(); r != nil {
354
+			switch a.Action {
355
+			case api.AssignmentChange_AssignmentActionUpdate:
356
+				updatedConfigs = append(updatedConfigs, *r)
357
+			case api.AssignmentChange_AssignmentActionRemove:
358
+				removedConfigs = append(removedConfigs, r.ID)
359
+			}
360
+
361
+		}
362
+	}
363
+
364
+	configsProvider, ok := w.executor.(exec.ConfigsProvider)
365
+	if !ok {
366
+		if len(updatedConfigs) != 0 || len(removedConfigs) != 0 {
367
+			log.G(ctx).Warn("configs update ignored; executor does not support configs")
368
+		}
369
+		return nil
370
+	}
371
+
372
+	configs := configsProvider.Configs()
373
+
374
+	log.G(ctx).WithFields(logrus.Fields{
375
+		"len(updatedConfigs)": len(updatedConfigs),
376
+		"len(removedConfigs)": len(removedConfigs),
377
+	}).Debug("(*worker).reconcileConfigs")
378
+
379
+	// If this was a complete set of configs, we're going to clear the configs map and add all of them
380
+	if fullSnapshot {
381
+		configs.Reset()
382
+	} else {
383
+		configs.Remove(removedConfigs)
384
+	}
385
+	configs.Add(updatedConfigs...)
386
+
387
+	return nil
388
+}
389
+
347 390
 func (w *worker) Listen(ctx context.Context, reporter StatusReporter) {
348 391
 	w.mu.Lock()
349 392
 	defer w.mu.Unlock()
... ...
@@ -567,7 +567,7 @@ func (m *CreateSecretRequest) Reset()                    { *m = CreateSecretRequ
567 567
 func (*CreateSecretRequest) ProtoMessage()               {}
568 568
 func (*CreateSecretRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{45} }
569 569
 
570
-// CreateSecretResponse contains the newly created `Secret`` corresponding to the
570
+// CreateSecretResponse contains the newly created `Secret` corresponding to the
571 571
 // name in `CreateSecretRequest`.  The `Secret.Spec.Data` field should be nil instead
572 572
 // of actually containing the secret bytes.
573 573
 type CreateSecretResponse struct {
... ...
@@ -597,6 +597,119 @@ func (m *RemoveSecretResponse) Reset()                    { *m = RemoveSecretRes
597 597
 func (*RemoveSecretResponse) ProtoMessage()               {}
598 598
 func (*RemoveSecretResponse) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{48} }
599 599
 
600
+// GetConfigRequest is the request to get a `Config` object given a config id.
601
+type GetConfigRequest struct {
602
+	ConfigID string `protobuf:"bytes,1,opt,name=config_id,json=configId,proto3" json:"config_id,omitempty"`
603
+}
604
+
605
+func (m *GetConfigRequest) Reset()                    { *m = GetConfigRequest{} }
606
+func (*GetConfigRequest) ProtoMessage()               {}
607
+func (*GetConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{49} }
608
+
609
+// GetConfigResponse contains the Config corresponding to the id in
610
+// `GetConfigRequest`.
611
+type GetConfigResponse struct {
612
+	Config *Config `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
613
+}
614
+
615
+func (m *GetConfigResponse) Reset()                    { *m = GetConfigResponse{} }
616
+func (*GetConfigResponse) ProtoMessage()               {}
617
+func (*GetConfigResponse) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{50} }
618
+
619
+type UpdateConfigRequest struct {
620
+	// ConfigID is the config ID to update.
621
+	ConfigID string `protobuf:"bytes,1,opt,name=config_id,json=configId,proto3" json:"config_id,omitempty"`
622
+	// ConfigVersion is the version of the config being updated.
623
+	ConfigVersion *Version `protobuf:"bytes,2,opt,name=config_version,json=configVersion" json:"config_version,omitempty"`
624
+	// Spec is the new spec to apply to the Config
625
+	// Only some fields are allowed to be updated.
626
+	Spec *ConfigSpec `protobuf:"bytes,3,opt,name=spec" json:"spec,omitempty"`
627
+}
628
+
629
+func (m *UpdateConfigRequest) Reset()                    { *m = UpdateConfigRequest{} }
630
+func (*UpdateConfigRequest) ProtoMessage()               {}
631
+func (*UpdateConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{51} }
632
+
633
+type UpdateConfigResponse struct {
634
+	Config *Config `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
635
+}
636
+
637
+func (m *UpdateConfigResponse) Reset()                    { *m = UpdateConfigResponse{} }
638
+func (*UpdateConfigResponse) ProtoMessage()               {}
639
+func (*UpdateConfigResponse) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{52} }
640
+
641
+// ListConfigRequest is the request to list all configs in the config store,
642
+// or all configs filtered by (name or name prefix or id prefix) and labels.
643
+type ListConfigsRequest struct {
644
+	Filters *ListConfigsRequest_Filters `protobuf:"bytes,1,opt,name=filters" json:"filters,omitempty"`
645
+}
646
+
647
+func (m *ListConfigsRequest) Reset()                    { *m = ListConfigsRequest{} }
648
+func (*ListConfigsRequest) ProtoMessage()               {}
649
+func (*ListConfigsRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{53} }
650
+
651
+type ListConfigsRequest_Filters struct {
652
+	Names        []string          `protobuf:"bytes,1,rep,name=names" json:"names,omitempty"`
653
+	IDPrefixes   []string          `protobuf:"bytes,2,rep,name=id_prefixes,json=idPrefixes" json:"id_prefixes,omitempty"`
654
+	Labels       map[string]string `protobuf:"bytes,3,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
655
+	NamePrefixes []string          `protobuf:"bytes,4,rep,name=name_prefixes,json=namePrefixes" json:"name_prefixes,omitempty"`
656
+}
657
+
658
+func (m *ListConfigsRequest_Filters) Reset()      { *m = ListConfigsRequest_Filters{} }
659
+func (*ListConfigsRequest_Filters) ProtoMessage() {}
660
+func (*ListConfigsRequest_Filters) Descriptor() ([]byte, []int) {
661
+	return fileDescriptorControl, []int{53, 0}
662
+}
663
+
664
+// ListConfigResponse contains a list of all the configs that match the name or
665
+// name prefix filters provided in `ListConfigRequest`.
666
+type ListConfigsResponse struct {
667
+	Configs []*Config `protobuf:"bytes,1,rep,name=configs" json:"configs,omitempty"`
668
+}
669
+
670
+func (m *ListConfigsResponse) Reset()                    { *m = ListConfigsResponse{} }
671
+func (*ListConfigsResponse) ProtoMessage()               {}
672
+func (*ListConfigsResponse) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{54} }
673
+
674
+// CreateConfigRequest specifies a new config (it will not update an existing
675
+// config) to create.
676
+type CreateConfigRequest struct {
677
+	Spec *ConfigSpec `protobuf:"bytes,1,opt,name=spec" json:"spec,omitempty"`
678
+}
679
+
680
+func (m *CreateConfigRequest) Reset()                    { *m = CreateConfigRequest{} }
681
+func (*CreateConfigRequest) ProtoMessage()               {}
682
+func (*CreateConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{55} }
683
+
684
+// CreateConfigResponse contains the newly created `Config` corresponding to the
685
+// name in `CreateConfigRequest`.
686
+type CreateConfigResponse struct {
687
+	Config *Config `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"`
688
+}
689
+
690
+func (m *CreateConfigResponse) Reset()                    { *m = CreateConfigResponse{} }
691
+func (*CreateConfigResponse) ProtoMessage()               {}
692
+func (*CreateConfigResponse) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{56} }
693
+
694
+// RemoveConfigRequest contains the ID of the config that should be removed.  This
695
+// removes all versions of the config.
696
+type RemoveConfigRequest struct {
697
+	ConfigID string `protobuf:"bytes,1,opt,name=config_id,json=configId,proto3" json:"config_id,omitempty"`
698
+}
699
+
700
+func (m *RemoveConfigRequest) Reset()                    { *m = RemoveConfigRequest{} }
701
+func (*RemoveConfigRequest) ProtoMessage()               {}
702
+func (*RemoveConfigRequest) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{57} }
703
+
704
+// RemoveConfigResponse is an empty object indicating the successful removal of
705
+// a config.
706
+type RemoveConfigResponse struct {
707
+}
708
+
709
+func (m *RemoveConfigResponse) Reset()                    { *m = RemoveConfigResponse{} }
710
+func (*RemoveConfigResponse) ProtoMessage()               {}
711
+func (*RemoveConfigResponse) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{58} }
712
+
600 713
 func init() {
601 714
 	proto.RegisterType((*GetNodeRequest)(nil), "docker.swarmkit.v1.GetNodeRequest")
602 715
 	proto.RegisterType((*GetNodeResponse)(nil), "docker.swarmkit.v1.GetNodeResponse")
... ...
@@ -653,6 +766,17 @@ func init() {
653 653
 	proto.RegisterType((*CreateSecretResponse)(nil), "docker.swarmkit.v1.CreateSecretResponse")
654 654
 	proto.RegisterType((*RemoveSecretRequest)(nil), "docker.swarmkit.v1.RemoveSecretRequest")
655 655
 	proto.RegisterType((*RemoveSecretResponse)(nil), "docker.swarmkit.v1.RemoveSecretResponse")
656
+	proto.RegisterType((*GetConfigRequest)(nil), "docker.swarmkit.v1.GetConfigRequest")
657
+	proto.RegisterType((*GetConfigResponse)(nil), "docker.swarmkit.v1.GetConfigResponse")
658
+	proto.RegisterType((*UpdateConfigRequest)(nil), "docker.swarmkit.v1.UpdateConfigRequest")
659
+	proto.RegisterType((*UpdateConfigResponse)(nil), "docker.swarmkit.v1.UpdateConfigResponse")
660
+	proto.RegisterType((*ListConfigsRequest)(nil), "docker.swarmkit.v1.ListConfigsRequest")
661
+	proto.RegisterType((*ListConfigsRequest_Filters)(nil), "docker.swarmkit.v1.ListConfigsRequest.Filters")
662
+	proto.RegisterType((*ListConfigsResponse)(nil), "docker.swarmkit.v1.ListConfigsResponse")
663
+	proto.RegisterType((*CreateConfigRequest)(nil), "docker.swarmkit.v1.CreateConfigRequest")
664
+	proto.RegisterType((*CreateConfigResponse)(nil), "docker.swarmkit.v1.CreateConfigResponse")
665
+	proto.RegisterType((*RemoveConfigRequest)(nil), "docker.swarmkit.v1.RemoveConfigRequest")
666
+	proto.RegisterType((*RemoveConfigResponse)(nil), "docker.swarmkit.v1.RemoveConfigResponse")
656 667
 	proto.RegisterEnum("docker.swarmkit.v1.UpdateServiceRequest_Rollback", UpdateServiceRequest_Rollback_name, UpdateServiceRequest_Rollback_value)
657 668
 }
658 669
 
... ...
@@ -860,6 +984,46 @@ func (p *authenticatedWrapperControlServer) RemoveSecret(ctx context.Context, r
860 860
 	return p.local.RemoveSecret(ctx, r)
861 861
 }
862 862
 
863
+func (p *authenticatedWrapperControlServer) GetConfig(ctx context.Context, r *GetConfigRequest) (*GetConfigResponse, error) {
864
+
865
+	if err := p.authorize(ctx, []string{"swarm-manager"}); err != nil {
866
+		return nil, err
867
+	}
868
+	return p.local.GetConfig(ctx, r)
869
+}
870
+
871
+func (p *authenticatedWrapperControlServer) UpdateConfig(ctx context.Context, r *UpdateConfigRequest) (*UpdateConfigResponse, error) {
872
+
873
+	if err := p.authorize(ctx, []string{"swarm-manager"}); err != nil {
874
+		return nil, err
875
+	}
876
+	return p.local.UpdateConfig(ctx, r)
877
+}
878
+
879
+func (p *authenticatedWrapperControlServer) ListConfigs(ctx context.Context, r *ListConfigsRequest) (*ListConfigsResponse, error) {
880
+
881
+	if err := p.authorize(ctx, []string{"swarm-manager"}); err != nil {
882
+		return nil, err
883
+	}
884
+	return p.local.ListConfigs(ctx, r)
885
+}
886
+
887
+func (p *authenticatedWrapperControlServer) CreateConfig(ctx context.Context, r *CreateConfigRequest) (*CreateConfigResponse, error) {
888
+
889
+	if err := p.authorize(ctx, []string{"swarm-manager"}); err != nil {
890
+		return nil, err
891
+	}
892
+	return p.local.CreateConfig(ctx, r)
893
+}
894
+
895
+func (p *authenticatedWrapperControlServer) RemoveConfig(ctx context.Context, r *RemoveConfigRequest) (*RemoveConfigResponse, error) {
896
+
897
+	if err := p.authorize(ctx, []string{"swarm-manager"}); err != nil {
898
+		return nil, err
899
+	}
900
+	return p.local.RemoveConfig(ctx, r)
901
+}
902
+
863 903
 func (m *GetNodeRequest) Copy() *GetNodeRequest {
864 904
 	if m == nil {
865 905
 		return nil
... ...
@@ -1996,6 +2160,224 @@ func (m *RemoveSecretResponse) Copy() *RemoveSecretResponse {
1996 1996
 }
1997 1997
 
1998 1998
 func (m *RemoveSecretResponse) CopyFrom(src interface{}) {}
1999
+func (m *GetConfigRequest) Copy() *GetConfigRequest {
2000
+	if m == nil {
2001
+		return nil
2002
+	}
2003
+	o := &GetConfigRequest{}
2004
+	o.CopyFrom(m)
2005
+	return o
2006
+}
2007
+
2008
+func (m *GetConfigRequest) CopyFrom(src interface{}) {
2009
+
2010
+	o := src.(*GetConfigRequest)
2011
+	*m = *o
2012
+}
2013
+
2014
+func (m *GetConfigResponse) Copy() *GetConfigResponse {
2015
+	if m == nil {
2016
+		return nil
2017
+	}
2018
+	o := &GetConfigResponse{}
2019
+	o.CopyFrom(m)
2020
+	return o
2021
+}
2022
+
2023
+func (m *GetConfigResponse) CopyFrom(src interface{}) {
2024
+
2025
+	o := src.(*GetConfigResponse)
2026
+	*m = *o
2027
+	if o.Config != nil {
2028
+		m.Config = &Config{}
2029
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Config, o.Config)
2030
+	}
2031
+}
2032
+
2033
+func (m *UpdateConfigRequest) Copy() *UpdateConfigRequest {
2034
+	if m == nil {
2035
+		return nil
2036
+	}
2037
+	o := &UpdateConfigRequest{}
2038
+	o.CopyFrom(m)
2039
+	return o
2040
+}
2041
+
2042
+func (m *UpdateConfigRequest) CopyFrom(src interface{}) {
2043
+
2044
+	o := src.(*UpdateConfigRequest)
2045
+	*m = *o
2046
+	if o.ConfigVersion != nil {
2047
+		m.ConfigVersion = &Version{}
2048
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.ConfigVersion, o.ConfigVersion)
2049
+	}
2050
+	if o.Spec != nil {
2051
+		m.Spec = &ConfigSpec{}
2052
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Spec, o.Spec)
2053
+	}
2054
+}
2055
+
2056
+func (m *UpdateConfigResponse) Copy() *UpdateConfigResponse {
2057
+	if m == nil {
2058
+		return nil
2059
+	}
2060
+	o := &UpdateConfigResponse{}
2061
+	o.CopyFrom(m)
2062
+	return o
2063
+}
2064
+
2065
+func (m *UpdateConfigResponse) CopyFrom(src interface{}) {
2066
+
2067
+	o := src.(*UpdateConfigResponse)
2068
+	*m = *o
2069
+	if o.Config != nil {
2070
+		m.Config = &Config{}
2071
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Config, o.Config)
2072
+	}
2073
+}
2074
+
2075
+func (m *ListConfigsRequest) Copy() *ListConfigsRequest {
2076
+	if m == nil {
2077
+		return nil
2078
+	}
2079
+	o := &ListConfigsRequest{}
2080
+	o.CopyFrom(m)
2081
+	return o
2082
+}
2083
+
2084
+func (m *ListConfigsRequest) CopyFrom(src interface{}) {
2085
+
2086
+	o := src.(*ListConfigsRequest)
2087
+	*m = *o
2088
+	if o.Filters != nil {
2089
+		m.Filters = &ListConfigsRequest_Filters{}
2090
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Filters, o.Filters)
2091
+	}
2092
+}
2093
+
2094
+func (m *ListConfigsRequest_Filters) Copy() *ListConfigsRequest_Filters {
2095
+	if m == nil {
2096
+		return nil
2097
+	}
2098
+	o := &ListConfigsRequest_Filters{}
2099
+	o.CopyFrom(m)
2100
+	return o
2101
+}
2102
+
2103
+func (m *ListConfigsRequest_Filters) CopyFrom(src interface{}) {
2104
+
2105
+	o := src.(*ListConfigsRequest_Filters)
2106
+	*m = *o
2107
+	if o.Names != nil {
2108
+		m.Names = make([]string, len(o.Names))
2109
+		copy(m.Names, o.Names)
2110
+	}
2111
+
2112
+	if o.IDPrefixes != nil {
2113
+		m.IDPrefixes = make([]string, len(o.IDPrefixes))
2114
+		copy(m.IDPrefixes, o.IDPrefixes)
2115
+	}
2116
+
2117
+	if o.Labels != nil {
2118
+		m.Labels = make(map[string]string, len(o.Labels))
2119
+		for k, v := range o.Labels {
2120
+			m.Labels[k] = v
2121
+		}
2122
+	}
2123
+
2124
+	if o.NamePrefixes != nil {
2125
+		m.NamePrefixes = make([]string, len(o.NamePrefixes))
2126
+		copy(m.NamePrefixes, o.NamePrefixes)
2127
+	}
2128
+
2129
+}
2130
+
2131
+func (m *ListConfigsResponse) Copy() *ListConfigsResponse {
2132
+	if m == nil {
2133
+		return nil
2134
+	}
2135
+	o := &ListConfigsResponse{}
2136
+	o.CopyFrom(m)
2137
+	return o
2138
+}
2139
+
2140
+func (m *ListConfigsResponse) CopyFrom(src interface{}) {
2141
+
2142
+	o := src.(*ListConfigsResponse)
2143
+	*m = *o
2144
+	if o.Configs != nil {
2145
+		m.Configs = make([]*Config, len(o.Configs))
2146
+		for i := range m.Configs {
2147
+			m.Configs[i] = &Config{}
2148
+			github_com_docker_swarmkit_api_deepcopy.Copy(m.Configs[i], o.Configs[i])
2149
+		}
2150
+	}
2151
+
2152
+}
2153
+
2154
+func (m *CreateConfigRequest) Copy() *CreateConfigRequest {
2155
+	if m == nil {
2156
+		return nil
2157
+	}
2158
+	o := &CreateConfigRequest{}
2159
+	o.CopyFrom(m)
2160
+	return o
2161
+}
2162
+
2163
+func (m *CreateConfigRequest) CopyFrom(src interface{}) {
2164
+
2165
+	o := src.(*CreateConfigRequest)
2166
+	*m = *o
2167
+	if o.Spec != nil {
2168
+		m.Spec = &ConfigSpec{}
2169
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Spec, o.Spec)
2170
+	}
2171
+}
2172
+
2173
+func (m *CreateConfigResponse) Copy() *CreateConfigResponse {
2174
+	if m == nil {
2175
+		return nil
2176
+	}
2177
+	o := &CreateConfigResponse{}
2178
+	o.CopyFrom(m)
2179
+	return o
2180
+}
2181
+
2182
+func (m *CreateConfigResponse) CopyFrom(src interface{}) {
2183
+
2184
+	o := src.(*CreateConfigResponse)
2185
+	*m = *o
2186
+	if o.Config != nil {
2187
+		m.Config = &Config{}
2188
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Config, o.Config)
2189
+	}
2190
+}
2191
+
2192
+func (m *RemoveConfigRequest) Copy() *RemoveConfigRequest {
2193
+	if m == nil {
2194
+		return nil
2195
+	}
2196
+	o := &RemoveConfigRequest{}
2197
+	o.CopyFrom(m)
2198
+	return o
2199
+}
2200
+
2201
+func (m *RemoveConfigRequest) CopyFrom(src interface{}) {
2202
+
2203
+	o := src.(*RemoveConfigRequest)
2204
+	*m = *o
2205
+}
2206
+
2207
+func (m *RemoveConfigResponse) Copy() *RemoveConfigResponse {
2208
+	if m == nil {
2209
+		return nil
2210
+	}
2211
+	o := &RemoveConfigResponse{}
2212
+	o.CopyFrom(m)
2213
+	return o
2214
+}
2215
+
2216
+func (m *RemoveConfigResponse) CopyFrom(src interface{}) {}
1999 2217
 
2000 2218
 // Reference imports to suppress errors if they are not otherwise used.
2001 2219
 var _ context.Context
... ...
@@ -2039,7 +2421,7 @@ type ControlClient interface {
2039 2039
 	// - Returns `InvalidArgument` if the `GetSecretRequest.SecretID` is empty.
2040 2040
 	// - Returns an error if updating fails.
2041 2041
 	UpdateSecret(ctx context.Context, in *UpdateSecretRequest, opts ...grpc.CallOption) (*UpdateSecretResponse, error)
2042
-	// ListSecrets returns a `ListSecretResponse` with a list all non-internal `Secret`s being
2042
+	// ListSecrets returns a `ListSecretResponse` with a list of all non-internal `Secret`s being
2043 2043
 	// managed, or all secrets matching any name in `ListSecretsRequest.Names`, any
2044 2044
 	// name prefix in `ListSecretsRequest.NamePrefixes`, any id in
2045 2045
 	// `ListSecretsRequest.SecretIDs`, or any id prefix in `ListSecretsRequest.IDPrefixes`.
... ...
@@ -2056,6 +2438,35 @@ type ControlClient interface {
2056 2056
 	// - Returns `NotFound` if the a secret named `RemoveSecretRequest.ID` is not found.
2057 2057
 	// - Returns an error if the deletion fails.
2058 2058
 	RemoveSecret(ctx context.Context, in *RemoveSecretRequest, opts ...grpc.CallOption) (*RemoveSecretResponse, error)
2059
+	// GetConfig returns a `GetConfigResponse` with a `Config` with the same
2060
+	// id as `GetConfigRequest.ConfigID`
2061
+	// - Returns `NotFound` if the Config with the given id is not found.
2062
+	// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
2063
+	// - Returns an error if getting fails.
2064
+	GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error)
2065
+	// UpdateConfig returns a `UpdateConfigResponse` with a `Config` with the same
2066
+	// id as `GetConfigRequest.ConfigID`
2067
+	// - Returns `NotFound` if the Config with the given id is not found.
2068
+	// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
2069
+	// - Returns an error if updating fails.
2070
+	UpdateConfig(ctx context.Context, in *UpdateConfigRequest, opts ...grpc.CallOption) (*UpdateConfigResponse, error)
2071
+	// ListConfigs returns a `ListConfigResponse` with a list of `Config`s being
2072
+	// managed, or all configs matching any name in `ListConfigsRequest.Names`, any
2073
+	// name prefix in `ListConfigsRequest.NamePrefixes`, any id in
2074
+	// `ListConfigsRequest.ConfigIDs`, or any id prefix in `ListConfigsRequest.IDPrefixes`.
2075
+	// - Returns an error if listing fails.
2076
+	ListConfigs(ctx context.Context, in *ListConfigsRequest, opts ...grpc.CallOption) (*ListConfigsResponse, error)
2077
+	// CreateConfig creates and return a `CreateConfigResponse` with a `Config` based
2078
+	// on the provided `CreateConfigRequest.ConfigSpec`.
2079
+	// - Returns `InvalidArgument` if the `CreateConfigRequest.ConfigSpec` is malformed,
2080
+	//   or if the config data is too long or contains invalid characters.
2081
+	// - Returns an error if the creation fails.
2082
+	CreateConfig(ctx context.Context, in *CreateConfigRequest, opts ...grpc.CallOption) (*CreateConfigResponse, error)
2083
+	// RemoveConfig removes the config referenced by `RemoveConfigRequest.ID`.
2084
+	// - Returns `InvalidArgument` if `RemoveConfigRequest.ID` is empty.
2085
+	// - Returns `NotFound` if the a config named `RemoveConfigRequest.ID` is not found.
2086
+	// - Returns an error if the deletion fails.
2087
+	RemoveConfig(ctx context.Context, in *RemoveConfigRequest, opts ...grpc.CallOption) (*RemoveConfigResponse, error)
2059 2088
 }
2060 2089
 
2061 2090
 type controlClient struct {
... ...
@@ -2282,6 +2693,51 @@ func (c *controlClient) RemoveSecret(ctx context.Context, in *RemoveSecretReques
2282 2282
 	return out, nil
2283 2283
 }
2284 2284
 
2285
+func (c *controlClient) GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error) {
2286
+	out := new(GetConfigResponse)
2287
+	err := grpc.Invoke(ctx, "/docker.swarmkit.v1.Control/GetConfig", in, out, c.cc, opts...)
2288
+	if err != nil {
2289
+		return nil, err
2290
+	}
2291
+	return out, nil
2292
+}
2293
+
2294
+func (c *controlClient) UpdateConfig(ctx context.Context, in *UpdateConfigRequest, opts ...grpc.CallOption) (*UpdateConfigResponse, error) {
2295
+	out := new(UpdateConfigResponse)
2296
+	err := grpc.Invoke(ctx, "/docker.swarmkit.v1.Control/UpdateConfig", in, out, c.cc, opts...)
2297
+	if err != nil {
2298
+		return nil, err
2299
+	}
2300
+	return out, nil
2301
+}
2302
+
2303
+func (c *controlClient) ListConfigs(ctx context.Context, in *ListConfigsRequest, opts ...grpc.CallOption) (*ListConfigsResponse, error) {
2304
+	out := new(ListConfigsResponse)
2305
+	err := grpc.Invoke(ctx, "/docker.swarmkit.v1.Control/ListConfigs", in, out, c.cc, opts...)
2306
+	if err != nil {
2307
+		return nil, err
2308
+	}
2309
+	return out, nil
2310
+}
2311
+
2312
+func (c *controlClient) CreateConfig(ctx context.Context, in *CreateConfigRequest, opts ...grpc.CallOption) (*CreateConfigResponse, error) {
2313
+	out := new(CreateConfigResponse)
2314
+	err := grpc.Invoke(ctx, "/docker.swarmkit.v1.Control/CreateConfig", in, out, c.cc, opts...)
2315
+	if err != nil {
2316
+		return nil, err
2317
+	}
2318
+	return out, nil
2319
+}
2320
+
2321
+func (c *controlClient) RemoveConfig(ctx context.Context, in *RemoveConfigRequest, opts ...grpc.CallOption) (*RemoveConfigResponse, error) {
2322
+	out := new(RemoveConfigResponse)
2323
+	err := grpc.Invoke(ctx, "/docker.swarmkit.v1.Control/RemoveConfig", in, out, c.cc, opts...)
2324
+	if err != nil {
2325
+		return nil, err
2326
+	}
2327
+	return out, nil
2328
+}
2329
+
2285 2330
 // Server API for Control service
2286 2331
 
2287 2332
 type ControlServer interface {
... ...
@@ -2316,7 +2772,7 @@ type ControlServer interface {
2316 2316
 	// - Returns `InvalidArgument` if the `GetSecretRequest.SecretID` is empty.
2317 2317
 	// - Returns an error if updating fails.
2318 2318
 	UpdateSecret(context.Context, *UpdateSecretRequest) (*UpdateSecretResponse, error)
2319
-	// ListSecrets returns a `ListSecretResponse` with a list all non-internal `Secret`s being
2319
+	// ListSecrets returns a `ListSecretResponse` with a list of all non-internal `Secret`s being
2320 2320
 	// managed, or all secrets matching any name in `ListSecretsRequest.Names`, any
2321 2321
 	// name prefix in `ListSecretsRequest.NamePrefixes`, any id in
2322 2322
 	// `ListSecretsRequest.SecretIDs`, or any id prefix in `ListSecretsRequest.IDPrefixes`.
... ...
@@ -2333,6 +2789,35 @@ type ControlServer interface {
2333 2333
 	// - Returns `NotFound` if the a secret named `RemoveSecretRequest.ID` is not found.
2334 2334
 	// - Returns an error if the deletion fails.
2335 2335
 	RemoveSecret(context.Context, *RemoveSecretRequest) (*RemoveSecretResponse, error)
2336
+	// GetConfig returns a `GetConfigResponse` with a `Config` with the same
2337
+	// id as `GetConfigRequest.ConfigID`
2338
+	// - Returns `NotFound` if the Config with the given id is not found.
2339
+	// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
2340
+	// - Returns an error if getting fails.
2341
+	GetConfig(context.Context, *GetConfigRequest) (*GetConfigResponse, error)
2342
+	// UpdateConfig returns a `UpdateConfigResponse` with a `Config` with the same
2343
+	// id as `GetConfigRequest.ConfigID`
2344
+	// - Returns `NotFound` if the Config with the given id is not found.
2345
+	// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
2346
+	// - Returns an error if updating fails.
2347
+	UpdateConfig(context.Context, *UpdateConfigRequest) (*UpdateConfigResponse, error)
2348
+	// ListConfigs returns a `ListConfigResponse` with a list of `Config`s being
2349
+	// managed, or all configs matching any name in `ListConfigsRequest.Names`, any
2350
+	// name prefix in `ListConfigsRequest.NamePrefixes`, any id in
2351
+	// `ListConfigsRequest.ConfigIDs`, or any id prefix in `ListConfigsRequest.IDPrefixes`.
2352
+	// - Returns an error if listing fails.
2353
+	ListConfigs(context.Context, *ListConfigsRequest) (*ListConfigsResponse, error)
2354
+	// CreateConfig creates and return a `CreateConfigResponse` with a `Config` based
2355
+	// on the provided `CreateConfigRequest.ConfigSpec`.
2356
+	// - Returns `InvalidArgument` if the `CreateConfigRequest.ConfigSpec` is malformed,
2357
+	//   or if the config data is too long or contains invalid characters.
2358
+	// - Returns an error if the creation fails.
2359
+	CreateConfig(context.Context, *CreateConfigRequest) (*CreateConfigResponse, error)
2360
+	// RemoveConfig removes the config referenced by `RemoveConfigRequest.ID`.
2361
+	// - Returns `InvalidArgument` if `RemoveConfigRequest.ID` is empty.
2362
+	// - Returns `NotFound` if the a config named `RemoveConfigRequest.ID` is not found.
2363
+	// - Returns an error if the deletion fails.
2364
+	RemoveConfig(context.Context, *RemoveConfigRequest) (*RemoveConfigResponse, error)
2336 2365
 }
2337 2366
 
2338 2367
 func RegisterControlServer(s *grpc.Server, srv ControlServer) {
... ...
@@ -2771,6 +3256,96 @@ func _Control_RemoveSecret_Handler(srv interface{}, ctx context.Context, dec fun
2771 2771
 	return interceptor(ctx, in, info, handler)
2772 2772
 }
2773 2773
 
2774
+func _Control_GetConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
2775
+	in := new(GetConfigRequest)
2776
+	if err := dec(in); err != nil {
2777
+		return nil, err
2778
+	}
2779
+	if interceptor == nil {
2780
+		return srv.(ControlServer).GetConfig(ctx, in)
2781
+	}
2782
+	info := &grpc.UnaryServerInfo{
2783
+		Server:     srv,
2784
+		FullMethod: "/docker.swarmkit.v1.Control/GetConfig",
2785
+	}
2786
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
2787
+		return srv.(ControlServer).GetConfig(ctx, req.(*GetConfigRequest))
2788
+	}
2789
+	return interceptor(ctx, in, info, handler)
2790
+}
2791
+
2792
+func _Control_UpdateConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
2793
+	in := new(UpdateConfigRequest)
2794
+	if err := dec(in); err != nil {
2795
+		return nil, err
2796
+	}
2797
+	if interceptor == nil {
2798
+		return srv.(ControlServer).UpdateConfig(ctx, in)
2799
+	}
2800
+	info := &grpc.UnaryServerInfo{
2801
+		Server:     srv,
2802
+		FullMethod: "/docker.swarmkit.v1.Control/UpdateConfig",
2803
+	}
2804
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
2805
+		return srv.(ControlServer).UpdateConfig(ctx, req.(*UpdateConfigRequest))
2806
+	}
2807
+	return interceptor(ctx, in, info, handler)
2808
+}
2809
+
2810
+func _Control_ListConfigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
2811
+	in := new(ListConfigsRequest)
2812
+	if err := dec(in); err != nil {
2813
+		return nil, err
2814
+	}
2815
+	if interceptor == nil {
2816
+		return srv.(ControlServer).ListConfigs(ctx, in)
2817
+	}
2818
+	info := &grpc.UnaryServerInfo{
2819
+		Server:     srv,
2820
+		FullMethod: "/docker.swarmkit.v1.Control/ListConfigs",
2821
+	}
2822
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
2823
+		return srv.(ControlServer).ListConfigs(ctx, req.(*ListConfigsRequest))
2824
+	}
2825
+	return interceptor(ctx, in, info, handler)
2826
+}
2827
+
2828
+func _Control_CreateConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
2829
+	in := new(CreateConfigRequest)
2830
+	if err := dec(in); err != nil {
2831
+		return nil, err
2832
+	}
2833
+	if interceptor == nil {
2834
+		return srv.(ControlServer).CreateConfig(ctx, in)
2835
+	}
2836
+	info := &grpc.UnaryServerInfo{
2837
+		Server:     srv,
2838
+		FullMethod: "/docker.swarmkit.v1.Control/CreateConfig",
2839
+	}
2840
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
2841
+		return srv.(ControlServer).CreateConfig(ctx, req.(*CreateConfigRequest))
2842
+	}
2843
+	return interceptor(ctx, in, info, handler)
2844
+}
2845
+
2846
+func _Control_RemoveConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
2847
+	in := new(RemoveConfigRequest)
2848
+	if err := dec(in); err != nil {
2849
+		return nil, err
2850
+	}
2851
+	if interceptor == nil {
2852
+		return srv.(ControlServer).RemoveConfig(ctx, in)
2853
+	}
2854
+	info := &grpc.UnaryServerInfo{
2855
+		Server:     srv,
2856
+		FullMethod: "/docker.swarmkit.v1.Control/RemoveConfig",
2857
+	}
2858
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
2859
+		return srv.(ControlServer).RemoveConfig(ctx, req.(*RemoveConfigRequest))
2860
+	}
2861
+	return interceptor(ctx, in, info, handler)
2862
+}
2863
+
2774 2864
 var _Control_serviceDesc = grpc.ServiceDesc{
2775 2865
 	ServiceName: "docker.swarmkit.v1.Control",
2776 2866
 	HandlerType: (*ControlServer)(nil),
... ...
@@ -2871,6 +3446,26 @@ var _Control_serviceDesc = grpc.ServiceDesc{
2871 2871
 			MethodName: "RemoveSecret",
2872 2872
 			Handler:    _Control_RemoveSecret_Handler,
2873 2873
 		},
2874
+		{
2875
+			MethodName: "GetConfig",
2876
+			Handler:    _Control_GetConfig_Handler,
2877
+		},
2878
+		{
2879
+			MethodName: "UpdateConfig",
2880
+			Handler:    _Control_UpdateConfig_Handler,
2881
+		},
2882
+		{
2883
+			MethodName: "ListConfigs",
2884
+			Handler:    _Control_ListConfigs_Handler,
2885
+		},
2886
+		{
2887
+			MethodName: "CreateConfig",
2888
+			Handler:    _Control_CreateConfig_Handler,
2889
+		},
2890
+		{
2891
+			MethodName: "RemoveConfig",
2892
+			Handler:    _Control_RemoveConfig_Handler,
2893
+		},
2874 2894
 	},
2875 2895
 	Streams:  []grpc.StreamDesc{},
2876 2896
 	Metadata: "control.proto",
... ...
@@ -4896,6 +5491,366 @@ func (m *RemoveSecretResponse) MarshalTo(dAtA []byte) (int, error) {
4896 4896
 	return i, nil
4897 4897
 }
4898 4898
 
4899
+func (m *GetConfigRequest) Marshal() (dAtA []byte, err error) {
4900
+	size := m.Size()
4901
+	dAtA = make([]byte, size)
4902
+	n, err := m.MarshalTo(dAtA)
4903
+	if err != nil {
4904
+		return nil, err
4905
+	}
4906
+	return dAtA[:n], nil
4907
+}
4908
+
4909
+func (m *GetConfigRequest) MarshalTo(dAtA []byte) (int, error) {
4910
+	var i int
4911
+	_ = i
4912
+	var l int
4913
+	_ = l
4914
+	if len(m.ConfigID) > 0 {
4915
+		dAtA[i] = 0xa
4916
+		i++
4917
+		i = encodeVarintControl(dAtA, i, uint64(len(m.ConfigID)))
4918
+		i += copy(dAtA[i:], m.ConfigID)
4919
+	}
4920
+	return i, nil
4921
+}
4922
+
4923
+func (m *GetConfigResponse) Marshal() (dAtA []byte, err error) {
4924
+	size := m.Size()
4925
+	dAtA = make([]byte, size)
4926
+	n, err := m.MarshalTo(dAtA)
4927
+	if err != nil {
4928
+		return nil, err
4929
+	}
4930
+	return dAtA[:n], nil
4931
+}
4932
+
4933
+func (m *GetConfigResponse) MarshalTo(dAtA []byte) (int, error) {
4934
+	var i int
4935
+	_ = i
4936
+	var l int
4937
+	_ = l
4938
+	if m.Config != nil {
4939
+		dAtA[i] = 0xa
4940
+		i++
4941
+		i = encodeVarintControl(dAtA, i, uint64(m.Config.Size()))
4942
+		n38, err := m.Config.MarshalTo(dAtA[i:])
4943
+		if err != nil {
4944
+			return 0, err
4945
+		}
4946
+		i += n38
4947
+	}
4948
+	return i, nil
4949
+}
4950
+
4951
+func (m *UpdateConfigRequest) Marshal() (dAtA []byte, err error) {
4952
+	size := m.Size()
4953
+	dAtA = make([]byte, size)
4954
+	n, err := m.MarshalTo(dAtA)
4955
+	if err != nil {
4956
+		return nil, err
4957
+	}
4958
+	return dAtA[:n], nil
4959
+}
4960
+
4961
+func (m *UpdateConfigRequest) MarshalTo(dAtA []byte) (int, error) {
4962
+	var i int
4963
+	_ = i
4964
+	var l int
4965
+	_ = l
4966
+	if len(m.ConfigID) > 0 {
4967
+		dAtA[i] = 0xa
4968
+		i++
4969
+		i = encodeVarintControl(dAtA, i, uint64(len(m.ConfigID)))
4970
+		i += copy(dAtA[i:], m.ConfigID)
4971
+	}
4972
+	if m.ConfigVersion != nil {
4973
+		dAtA[i] = 0x12
4974
+		i++
4975
+		i = encodeVarintControl(dAtA, i, uint64(m.ConfigVersion.Size()))
4976
+		n39, err := m.ConfigVersion.MarshalTo(dAtA[i:])
4977
+		if err != nil {
4978
+			return 0, err
4979
+		}
4980
+		i += n39
4981
+	}
4982
+	if m.Spec != nil {
4983
+		dAtA[i] = 0x1a
4984
+		i++
4985
+		i = encodeVarintControl(dAtA, i, uint64(m.Spec.Size()))
4986
+		n40, err := m.Spec.MarshalTo(dAtA[i:])
4987
+		if err != nil {
4988
+			return 0, err
4989
+		}
4990
+		i += n40
4991
+	}
4992
+	return i, nil
4993
+}
4994
+
4995
+func (m *UpdateConfigResponse) Marshal() (dAtA []byte, err error) {
4996
+	size := m.Size()
4997
+	dAtA = make([]byte, size)
4998
+	n, err := m.MarshalTo(dAtA)
4999
+	if err != nil {
5000
+		return nil, err
5001
+	}
5002
+	return dAtA[:n], nil
5003
+}
5004
+
5005
+func (m *UpdateConfigResponse) MarshalTo(dAtA []byte) (int, error) {
5006
+	var i int
5007
+	_ = i
5008
+	var l int
5009
+	_ = l
5010
+	if m.Config != nil {
5011
+		dAtA[i] = 0xa
5012
+		i++
5013
+		i = encodeVarintControl(dAtA, i, uint64(m.Config.Size()))
5014
+		n41, err := m.Config.MarshalTo(dAtA[i:])
5015
+		if err != nil {
5016
+			return 0, err
5017
+		}
5018
+		i += n41
5019
+	}
5020
+	return i, nil
5021
+}
5022
+
5023
+func (m *ListConfigsRequest) Marshal() (dAtA []byte, err error) {
5024
+	size := m.Size()
5025
+	dAtA = make([]byte, size)
5026
+	n, err := m.MarshalTo(dAtA)
5027
+	if err != nil {
5028
+		return nil, err
5029
+	}
5030
+	return dAtA[:n], nil
5031
+}
5032
+
5033
+func (m *ListConfigsRequest) MarshalTo(dAtA []byte) (int, error) {
5034
+	var i int
5035
+	_ = i
5036
+	var l int
5037
+	_ = l
5038
+	if m.Filters != nil {
5039
+		dAtA[i] = 0xa
5040
+		i++
5041
+		i = encodeVarintControl(dAtA, i, uint64(m.Filters.Size()))
5042
+		n42, err := m.Filters.MarshalTo(dAtA[i:])
5043
+		if err != nil {
5044
+			return 0, err
5045
+		}
5046
+		i += n42
5047
+	}
5048
+	return i, nil
5049
+}
5050
+
5051
+func (m *ListConfigsRequest_Filters) Marshal() (dAtA []byte, err error) {
5052
+	size := m.Size()
5053
+	dAtA = make([]byte, size)
5054
+	n, err := m.MarshalTo(dAtA)
5055
+	if err != nil {
5056
+		return nil, err
5057
+	}
5058
+	return dAtA[:n], nil
5059
+}
5060
+
5061
+func (m *ListConfigsRequest_Filters) MarshalTo(dAtA []byte) (int, error) {
5062
+	var i int
5063
+	_ = i
5064
+	var l int
5065
+	_ = l
5066
+	if len(m.Names) > 0 {
5067
+		for _, s := range m.Names {
5068
+			dAtA[i] = 0xa
5069
+			i++
5070
+			l = len(s)
5071
+			for l >= 1<<7 {
5072
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
5073
+				l >>= 7
5074
+				i++
5075
+			}
5076
+			dAtA[i] = uint8(l)
5077
+			i++
5078
+			i += copy(dAtA[i:], s)
5079
+		}
5080
+	}
5081
+	if len(m.IDPrefixes) > 0 {
5082
+		for _, s := range m.IDPrefixes {
5083
+			dAtA[i] = 0x12
5084
+			i++
5085
+			l = len(s)
5086
+			for l >= 1<<7 {
5087
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
5088
+				l >>= 7
5089
+				i++
5090
+			}
5091
+			dAtA[i] = uint8(l)
5092
+			i++
5093
+			i += copy(dAtA[i:], s)
5094
+		}
5095
+	}
5096
+	if len(m.Labels) > 0 {
5097
+		for k, _ := range m.Labels {
5098
+			dAtA[i] = 0x1a
5099
+			i++
5100
+			v := m.Labels[k]
5101
+			mapSize := 1 + len(k) + sovControl(uint64(len(k))) + 1 + len(v) + sovControl(uint64(len(v)))
5102
+			i = encodeVarintControl(dAtA, i, uint64(mapSize))
5103
+			dAtA[i] = 0xa
5104
+			i++
5105
+			i = encodeVarintControl(dAtA, i, uint64(len(k)))
5106
+			i += copy(dAtA[i:], k)
5107
+			dAtA[i] = 0x12
5108
+			i++
5109
+			i = encodeVarintControl(dAtA, i, uint64(len(v)))
5110
+			i += copy(dAtA[i:], v)
5111
+		}
5112
+	}
5113
+	if len(m.NamePrefixes) > 0 {
5114
+		for _, s := range m.NamePrefixes {
5115
+			dAtA[i] = 0x22
5116
+			i++
5117
+			l = len(s)
5118
+			for l >= 1<<7 {
5119
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
5120
+				l >>= 7
5121
+				i++
5122
+			}
5123
+			dAtA[i] = uint8(l)
5124
+			i++
5125
+			i += copy(dAtA[i:], s)
5126
+		}
5127
+	}
5128
+	return i, nil
5129
+}
5130
+
5131
+func (m *ListConfigsResponse) Marshal() (dAtA []byte, err error) {
5132
+	size := m.Size()
5133
+	dAtA = make([]byte, size)
5134
+	n, err := m.MarshalTo(dAtA)
5135
+	if err != nil {
5136
+		return nil, err
5137
+	}
5138
+	return dAtA[:n], nil
5139
+}
5140
+
5141
+func (m *ListConfigsResponse) MarshalTo(dAtA []byte) (int, error) {
5142
+	var i int
5143
+	_ = i
5144
+	var l int
5145
+	_ = l
5146
+	if len(m.Configs) > 0 {
5147
+		for _, msg := range m.Configs {
5148
+			dAtA[i] = 0xa
5149
+			i++
5150
+			i = encodeVarintControl(dAtA, i, uint64(msg.Size()))
5151
+			n, err := msg.MarshalTo(dAtA[i:])
5152
+			if err != nil {
5153
+				return 0, err
5154
+			}
5155
+			i += n
5156
+		}
5157
+	}
5158
+	return i, nil
5159
+}
5160
+
5161
+func (m *CreateConfigRequest) Marshal() (dAtA []byte, err error) {
5162
+	size := m.Size()
5163
+	dAtA = make([]byte, size)
5164
+	n, err := m.MarshalTo(dAtA)
5165
+	if err != nil {
5166
+		return nil, err
5167
+	}
5168
+	return dAtA[:n], nil
5169
+}
5170
+
5171
+func (m *CreateConfigRequest) MarshalTo(dAtA []byte) (int, error) {
5172
+	var i int
5173
+	_ = i
5174
+	var l int
5175
+	_ = l
5176
+	if m.Spec != nil {
5177
+		dAtA[i] = 0xa
5178
+		i++
5179
+		i = encodeVarintControl(dAtA, i, uint64(m.Spec.Size()))
5180
+		n43, err := m.Spec.MarshalTo(dAtA[i:])
5181
+		if err != nil {
5182
+			return 0, err
5183
+		}
5184
+		i += n43
5185
+	}
5186
+	return i, nil
5187
+}
5188
+
5189
+func (m *CreateConfigResponse) Marshal() (dAtA []byte, err error) {
5190
+	size := m.Size()
5191
+	dAtA = make([]byte, size)
5192
+	n, err := m.MarshalTo(dAtA)
5193
+	if err != nil {
5194
+		return nil, err
5195
+	}
5196
+	return dAtA[:n], nil
5197
+}
5198
+
5199
+func (m *CreateConfigResponse) MarshalTo(dAtA []byte) (int, error) {
5200
+	var i int
5201
+	_ = i
5202
+	var l int
5203
+	_ = l
5204
+	if m.Config != nil {
5205
+		dAtA[i] = 0xa
5206
+		i++
5207
+		i = encodeVarintControl(dAtA, i, uint64(m.Config.Size()))
5208
+		n44, err := m.Config.MarshalTo(dAtA[i:])
5209
+		if err != nil {
5210
+			return 0, err
5211
+		}
5212
+		i += n44
5213
+	}
5214
+	return i, nil
5215
+}
5216
+
5217
+func (m *RemoveConfigRequest) Marshal() (dAtA []byte, err error) {
5218
+	size := m.Size()
5219
+	dAtA = make([]byte, size)
5220
+	n, err := m.MarshalTo(dAtA)
5221
+	if err != nil {
5222
+		return nil, err
5223
+	}
5224
+	return dAtA[:n], nil
5225
+}
5226
+
5227
+func (m *RemoveConfigRequest) MarshalTo(dAtA []byte) (int, error) {
5228
+	var i int
5229
+	_ = i
5230
+	var l int
5231
+	_ = l
5232
+	if len(m.ConfigID) > 0 {
5233
+		dAtA[i] = 0xa
5234
+		i++
5235
+		i = encodeVarintControl(dAtA, i, uint64(len(m.ConfigID)))
5236
+		i += copy(dAtA[i:], m.ConfigID)
5237
+	}
5238
+	return i, nil
5239
+}
5240
+
5241
+func (m *RemoveConfigResponse) Marshal() (dAtA []byte, err error) {
5242
+	size := m.Size()
5243
+	dAtA = make([]byte, size)
5244
+	n, err := m.MarshalTo(dAtA)
5245
+	if err != nil {
5246
+		return nil, err
5247
+	}
5248
+	return dAtA[:n], nil
5249
+}
5250
+
5251
+func (m *RemoveConfigResponse) MarshalTo(dAtA []byte) (int, error) {
5252
+	var i int
5253
+	_ = i
5254
+	var l int
5255
+	_ = l
5256
+	return i, nil
5257
+}
5258
+
4899 5259
 func encodeFixed64Control(dAtA []byte, offset int, v uint64) int {
4900 5260
 	dAtA[offset] = uint8(v)
4901 5261
 	dAtA[offset+1] = uint8(v >> 8)
... ...
@@ -5836,6 +6791,181 @@ func (p *raftProxyControlServer) RemoveSecret(ctx context.Context, r *RemoveSecr
5836 5836
 	return resp, err
5837 5837
 }
5838 5838
 
5839
+func (p *raftProxyControlServer) GetConfig(ctx context.Context, r *GetConfigRequest) (*GetConfigResponse, error) {
5840
+
5841
+	conn, err := p.connSelector.LeaderConn(ctx)
5842
+	if err != nil {
5843
+		if err == raftselector.ErrIsLeader {
5844
+			ctx, err = p.runCtxMods(ctx, p.localCtxMods)
5845
+			if err != nil {
5846
+				return nil, err
5847
+			}
5848
+			return p.local.GetConfig(ctx, r)
5849
+		}
5850
+		return nil, err
5851
+	}
5852
+	modCtx, err := p.runCtxMods(ctx, p.remoteCtxMods)
5853
+	if err != nil {
5854
+		return nil, err
5855
+	}
5856
+
5857
+	resp, err := NewControlClient(conn).GetConfig(modCtx, r)
5858
+	if err != nil {
5859
+		if !strings.Contains(err.Error(), "is closing") && !strings.Contains(err.Error(), "the connection is unavailable") && !strings.Contains(err.Error(), "connection error") {
5860
+			return resp, err
5861
+		}
5862
+		conn, err := p.pollNewLeaderConn(ctx)
5863
+		if err != nil {
5864
+			if err == raftselector.ErrIsLeader {
5865
+				return p.local.GetConfig(ctx, r)
5866
+			}
5867
+			return nil, err
5868
+		}
5869
+		return NewControlClient(conn).GetConfig(modCtx, r)
5870
+	}
5871
+	return resp, err
5872
+}
5873
+
5874
+func (p *raftProxyControlServer) UpdateConfig(ctx context.Context, r *UpdateConfigRequest) (*UpdateConfigResponse, error) {
5875
+
5876
+	conn, err := p.connSelector.LeaderConn(ctx)
5877
+	if err != nil {
5878
+		if err == raftselector.ErrIsLeader {
5879
+			ctx, err = p.runCtxMods(ctx, p.localCtxMods)
5880
+			if err != nil {
5881
+				return nil, err
5882
+			}
5883
+			return p.local.UpdateConfig(ctx, r)
5884
+		}
5885
+		return nil, err
5886
+	}
5887
+	modCtx, err := p.runCtxMods(ctx, p.remoteCtxMods)
5888
+	if err != nil {
5889
+		return nil, err
5890
+	}
5891
+
5892
+	resp, err := NewControlClient(conn).UpdateConfig(modCtx, r)
5893
+	if err != nil {
5894
+		if !strings.Contains(err.Error(), "is closing") && !strings.Contains(err.Error(), "the connection is unavailable") && !strings.Contains(err.Error(), "connection error") {
5895
+			return resp, err
5896
+		}
5897
+		conn, err := p.pollNewLeaderConn(ctx)
5898
+		if err != nil {
5899
+			if err == raftselector.ErrIsLeader {
5900
+				return p.local.UpdateConfig(ctx, r)
5901
+			}
5902
+			return nil, err
5903
+		}
5904
+		return NewControlClient(conn).UpdateConfig(modCtx, r)
5905
+	}
5906
+	return resp, err
5907
+}
5908
+
5909
+func (p *raftProxyControlServer) ListConfigs(ctx context.Context, r *ListConfigsRequest) (*ListConfigsResponse, error) {
5910
+
5911
+	conn, err := p.connSelector.LeaderConn(ctx)
5912
+	if err != nil {
5913
+		if err == raftselector.ErrIsLeader {
5914
+			ctx, err = p.runCtxMods(ctx, p.localCtxMods)
5915
+			if err != nil {
5916
+				return nil, err
5917
+			}
5918
+			return p.local.ListConfigs(ctx, r)
5919
+		}
5920
+		return nil, err
5921
+	}
5922
+	modCtx, err := p.runCtxMods(ctx, p.remoteCtxMods)
5923
+	if err != nil {
5924
+		return nil, err
5925
+	}
5926
+
5927
+	resp, err := NewControlClient(conn).ListConfigs(modCtx, r)
5928
+	if err != nil {
5929
+		if !strings.Contains(err.Error(), "is closing") && !strings.Contains(err.Error(), "the connection is unavailable") && !strings.Contains(err.Error(), "connection error") {
5930
+			return resp, err
5931
+		}
5932
+		conn, err := p.pollNewLeaderConn(ctx)
5933
+		if err != nil {
5934
+			if err == raftselector.ErrIsLeader {
5935
+				return p.local.ListConfigs(ctx, r)
5936
+			}
5937
+			return nil, err
5938
+		}
5939
+		return NewControlClient(conn).ListConfigs(modCtx, r)
5940
+	}
5941
+	return resp, err
5942
+}
5943
+
5944
+func (p *raftProxyControlServer) CreateConfig(ctx context.Context, r *CreateConfigRequest) (*CreateConfigResponse, error) {
5945
+
5946
+	conn, err := p.connSelector.LeaderConn(ctx)
5947
+	if err != nil {
5948
+		if err == raftselector.ErrIsLeader {
5949
+			ctx, err = p.runCtxMods(ctx, p.localCtxMods)
5950
+			if err != nil {
5951
+				return nil, err
5952
+			}
5953
+			return p.local.CreateConfig(ctx, r)
5954
+		}
5955
+		return nil, err
5956
+	}
5957
+	modCtx, err := p.runCtxMods(ctx, p.remoteCtxMods)
5958
+	if err != nil {
5959
+		return nil, err
5960
+	}
5961
+
5962
+	resp, err := NewControlClient(conn).CreateConfig(modCtx, r)
5963
+	if err != nil {
5964
+		if !strings.Contains(err.Error(), "is closing") && !strings.Contains(err.Error(), "the connection is unavailable") && !strings.Contains(err.Error(), "connection error") {
5965
+			return resp, err
5966
+		}
5967
+		conn, err := p.pollNewLeaderConn(ctx)
5968
+		if err != nil {
5969
+			if err == raftselector.ErrIsLeader {
5970
+				return p.local.CreateConfig(ctx, r)
5971
+			}
5972
+			return nil, err
5973
+		}
5974
+		return NewControlClient(conn).CreateConfig(modCtx, r)
5975
+	}
5976
+	return resp, err
5977
+}
5978
+
5979
+func (p *raftProxyControlServer) RemoveConfig(ctx context.Context, r *RemoveConfigRequest) (*RemoveConfigResponse, error) {
5980
+
5981
+	conn, err := p.connSelector.LeaderConn(ctx)
5982
+	if err != nil {
5983
+		if err == raftselector.ErrIsLeader {
5984
+			ctx, err = p.runCtxMods(ctx, p.localCtxMods)
5985
+			if err != nil {
5986
+				return nil, err
5987
+			}
5988
+			return p.local.RemoveConfig(ctx, r)
5989
+		}
5990
+		return nil, err
5991
+	}
5992
+	modCtx, err := p.runCtxMods(ctx, p.remoteCtxMods)
5993
+	if err != nil {
5994
+		return nil, err
5995
+	}
5996
+
5997
+	resp, err := NewControlClient(conn).RemoveConfig(modCtx, r)
5998
+	if err != nil {
5999
+		if !strings.Contains(err.Error(), "is closing") && !strings.Contains(err.Error(), "the connection is unavailable") && !strings.Contains(err.Error(), "connection error") {
6000
+			return resp, err
6001
+		}
6002
+		conn, err := p.pollNewLeaderConn(ctx)
6003
+		if err != nil {
6004
+			if err == raftselector.ErrIsLeader {
6005
+				return p.local.RemoveConfig(ctx, r)
6006
+			}
6007
+			return nil, err
6008
+		}
6009
+		return NewControlClient(conn).RemoveConfig(modCtx, r)
6010
+	}
6011
+	return resp, err
6012
+}
6013
+
5839 6014
 func (m *GetNodeRequest) Size() (n int) {
5840 6015
 	var l int
5841 6016
 	_ = l
... ...
@@ -6614,6 +7744,144 @@ func (m *RemoveSecretResponse) Size() (n int) {
6614 6614
 	return n
6615 6615
 }
6616 6616
 
6617
+func (m *GetConfigRequest) Size() (n int) {
6618
+	var l int
6619
+	_ = l
6620
+	l = len(m.ConfigID)
6621
+	if l > 0 {
6622
+		n += 1 + l + sovControl(uint64(l))
6623
+	}
6624
+	return n
6625
+}
6626
+
6627
+func (m *GetConfigResponse) Size() (n int) {
6628
+	var l int
6629
+	_ = l
6630
+	if m.Config != nil {
6631
+		l = m.Config.Size()
6632
+		n += 1 + l + sovControl(uint64(l))
6633
+	}
6634
+	return n
6635
+}
6636
+
6637
+func (m *UpdateConfigRequest) Size() (n int) {
6638
+	var l int
6639
+	_ = l
6640
+	l = len(m.ConfigID)
6641
+	if l > 0 {
6642
+		n += 1 + l + sovControl(uint64(l))
6643
+	}
6644
+	if m.ConfigVersion != nil {
6645
+		l = m.ConfigVersion.Size()
6646
+		n += 1 + l + sovControl(uint64(l))
6647
+	}
6648
+	if m.Spec != nil {
6649
+		l = m.Spec.Size()
6650
+		n += 1 + l + sovControl(uint64(l))
6651
+	}
6652
+	return n
6653
+}
6654
+
6655
+func (m *UpdateConfigResponse) Size() (n int) {
6656
+	var l int
6657
+	_ = l
6658
+	if m.Config != nil {
6659
+		l = m.Config.Size()
6660
+		n += 1 + l + sovControl(uint64(l))
6661
+	}
6662
+	return n
6663
+}
6664
+
6665
+func (m *ListConfigsRequest) Size() (n int) {
6666
+	var l int
6667
+	_ = l
6668
+	if m.Filters != nil {
6669
+		l = m.Filters.Size()
6670
+		n += 1 + l + sovControl(uint64(l))
6671
+	}
6672
+	return n
6673
+}
6674
+
6675
+func (m *ListConfigsRequest_Filters) Size() (n int) {
6676
+	var l int
6677
+	_ = l
6678
+	if len(m.Names) > 0 {
6679
+		for _, s := range m.Names {
6680
+			l = len(s)
6681
+			n += 1 + l + sovControl(uint64(l))
6682
+		}
6683
+	}
6684
+	if len(m.IDPrefixes) > 0 {
6685
+		for _, s := range m.IDPrefixes {
6686
+			l = len(s)
6687
+			n += 1 + l + sovControl(uint64(l))
6688
+		}
6689
+	}
6690
+	if len(m.Labels) > 0 {
6691
+		for k, v := range m.Labels {
6692
+			_ = k
6693
+			_ = v
6694
+			mapEntrySize := 1 + len(k) + sovControl(uint64(len(k))) + 1 + len(v) + sovControl(uint64(len(v)))
6695
+			n += mapEntrySize + 1 + sovControl(uint64(mapEntrySize))
6696
+		}
6697
+	}
6698
+	if len(m.NamePrefixes) > 0 {
6699
+		for _, s := range m.NamePrefixes {
6700
+			l = len(s)
6701
+			n += 1 + l + sovControl(uint64(l))
6702
+		}
6703
+	}
6704
+	return n
6705
+}
6706
+
6707
+func (m *ListConfigsResponse) Size() (n int) {
6708
+	var l int
6709
+	_ = l
6710
+	if len(m.Configs) > 0 {
6711
+		for _, e := range m.Configs {
6712
+			l = e.Size()
6713
+			n += 1 + l + sovControl(uint64(l))
6714
+		}
6715
+	}
6716
+	return n
6717
+}
6718
+
6719
+func (m *CreateConfigRequest) Size() (n int) {
6720
+	var l int
6721
+	_ = l
6722
+	if m.Spec != nil {
6723
+		l = m.Spec.Size()
6724
+		n += 1 + l + sovControl(uint64(l))
6725
+	}
6726
+	return n
6727
+}
6728
+
6729
+func (m *CreateConfigResponse) Size() (n int) {
6730
+	var l int
6731
+	_ = l
6732
+	if m.Config != nil {
6733
+		l = m.Config.Size()
6734
+		n += 1 + l + sovControl(uint64(l))
6735
+	}
6736
+	return n
6737
+}
6738
+
6739
+func (m *RemoveConfigRequest) Size() (n int) {
6740
+	var l int
6741
+	_ = l
6742
+	l = len(m.ConfigID)
6743
+	if l > 0 {
6744
+		n += 1 + l + sovControl(uint64(l))
6745
+	}
6746
+	return n
6747
+}
6748
+
6749
+func (m *RemoveConfigResponse) Size() (n int) {
6750
+	var l int
6751
+	_ = l
6752
+	return n
6753
+}
6754
+
6617 6755
 func sovControl(x uint64) (n int) {
6618 6756
 	for {
6619 6757
 		n++
... ...
@@ -7274,6 +8542,130 @@ func (this *RemoveSecretResponse) String() string {
7274 7274
 	}, "")
7275 7275
 	return s
7276 7276
 }
7277
+func (this *GetConfigRequest) String() string {
7278
+	if this == nil {
7279
+		return "nil"
7280
+	}
7281
+	s := strings.Join([]string{`&GetConfigRequest{`,
7282
+		`ConfigID:` + fmt.Sprintf("%v", this.ConfigID) + `,`,
7283
+		`}`,
7284
+	}, "")
7285
+	return s
7286
+}
7287
+func (this *GetConfigResponse) String() string {
7288
+	if this == nil {
7289
+		return "nil"
7290
+	}
7291
+	s := strings.Join([]string{`&GetConfigResponse{`,
7292
+		`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
7293
+		`}`,
7294
+	}, "")
7295
+	return s
7296
+}
7297
+func (this *UpdateConfigRequest) String() string {
7298
+	if this == nil {
7299
+		return "nil"
7300
+	}
7301
+	s := strings.Join([]string{`&UpdateConfigRequest{`,
7302
+		`ConfigID:` + fmt.Sprintf("%v", this.ConfigID) + `,`,
7303
+		`ConfigVersion:` + strings.Replace(fmt.Sprintf("%v", this.ConfigVersion), "Version", "Version", 1) + `,`,
7304
+		`Spec:` + strings.Replace(fmt.Sprintf("%v", this.Spec), "ConfigSpec", "ConfigSpec", 1) + `,`,
7305
+		`}`,
7306
+	}, "")
7307
+	return s
7308
+}
7309
+func (this *UpdateConfigResponse) String() string {
7310
+	if this == nil {
7311
+		return "nil"
7312
+	}
7313
+	s := strings.Join([]string{`&UpdateConfigResponse{`,
7314
+		`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
7315
+		`}`,
7316
+	}, "")
7317
+	return s
7318
+}
7319
+func (this *ListConfigsRequest) String() string {
7320
+	if this == nil {
7321
+		return "nil"
7322
+	}
7323
+	s := strings.Join([]string{`&ListConfigsRequest{`,
7324
+		`Filters:` + strings.Replace(fmt.Sprintf("%v", this.Filters), "ListConfigsRequest_Filters", "ListConfigsRequest_Filters", 1) + `,`,
7325
+		`}`,
7326
+	}, "")
7327
+	return s
7328
+}
7329
+func (this *ListConfigsRequest_Filters) String() string {
7330
+	if this == nil {
7331
+		return "nil"
7332
+	}
7333
+	keysForLabels := make([]string, 0, len(this.Labels))
7334
+	for k, _ := range this.Labels {
7335
+		keysForLabels = append(keysForLabels, k)
7336
+	}
7337
+	github_com_gogo_protobuf_sortkeys.Strings(keysForLabels)
7338
+	mapStringForLabels := "map[string]string{"
7339
+	for _, k := range keysForLabels {
7340
+		mapStringForLabels += fmt.Sprintf("%v: %v,", k, this.Labels[k])
7341
+	}
7342
+	mapStringForLabels += "}"
7343
+	s := strings.Join([]string{`&ListConfigsRequest_Filters{`,
7344
+		`Names:` + fmt.Sprintf("%v", this.Names) + `,`,
7345
+		`IDPrefixes:` + fmt.Sprintf("%v", this.IDPrefixes) + `,`,
7346
+		`Labels:` + mapStringForLabels + `,`,
7347
+		`NamePrefixes:` + fmt.Sprintf("%v", this.NamePrefixes) + `,`,
7348
+		`}`,
7349
+	}, "")
7350
+	return s
7351
+}
7352
+func (this *ListConfigsResponse) String() string {
7353
+	if this == nil {
7354
+		return "nil"
7355
+	}
7356
+	s := strings.Join([]string{`&ListConfigsResponse{`,
7357
+		`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "Config", "Config", 1) + `,`,
7358
+		`}`,
7359
+	}, "")
7360
+	return s
7361
+}
7362
+func (this *CreateConfigRequest) String() string {
7363
+	if this == nil {
7364
+		return "nil"
7365
+	}
7366
+	s := strings.Join([]string{`&CreateConfigRequest{`,
7367
+		`Spec:` + strings.Replace(fmt.Sprintf("%v", this.Spec), "ConfigSpec", "ConfigSpec", 1) + `,`,
7368
+		`}`,
7369
+	}, "")
7370
+	return s
7371
+}
7372
+func (this *CreateConfigResponse) String() string {
7373
+	if this == nil {
7374
+		return "nil"
7375
+	}
7376
+	s := strings.Join([]string{`&CreateConfigResponse{`,
7377
+		`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
7378
+		`}`,
7379
+	}, "")
7380
+	return s
7381
+}
7382
+func (this *RemoveConfigRequest) String() string {
7383
+	if this == nil {
7384
+		return "nil"
7385
+	}
7386
+	s := strings.Join([]string{`&RemoveConfigRequest{`,
7387
+		`ConfigID:` + fmt.Sprintf("%v", this.ConfigID) + `,`,
7388
+		`}`,
7389
+	}, "")
7390
+	return s
7391
+}
7392
+func (this *RemoveConfigResponse) String() string {
7393
+	if this == nil {
7394
+		return "nil"
7395
+	}
7396
+	s := strings.Join([]string{`&RemoveConfigResponse{`,
7397
+		`}`,
7398
+	}, "")
7399
+	return s
7400
+}
7277 7401
 func valueToStringControl(v interface{}) string {
7278 7402
 	rv := reflect.ValueOf(v)
7279 7403
 	if rv.IsNil() {
... ...
@@ -13390,6 +14782,1108 @@ func (m *RemoveSecretResponse) Unmarshal(dAtA []byte) error {
13390 13390
 	}
13391 13391
 	return nil
13392 13392
 }
13393
+func (m *GetConfigRequest) Unmarshal(dAtA []byte) error {
13394
+	l := len(dAtA)
13395
+	iNdEx := 0
13396
+	for iNdEx < l {
13397
+		preIndex := iNdEx
13398
+		var wire uint64
13399
+		for shift := uint(0); ; shift += 7 {
13400
+			if shift >= 64 {
13401
+				return ErrIntOverflowControl
13402
+			}
13403
+			if iNdEx >= l {
13404
+				return io.ErrUnexpectedEOF
13405
+			}
13406
+			b := dAtA[iNdEx]
13407
+			iNdEx++
13408
+			wire |= (uint64(b) & 0x7F) << shift
13409
+			if b < 0x80 {
13410
+				break
13411
+			}
13412
+		}
13413
+		fieldNum := int32(wire >> 3)
13414
+		wireType := int(wire & 0x7)
13415
+		if wireType == 4 {
13416
+			return fmt.Errorf("proto: GetConfigRequest: wiretype end group for non-group")
13417
+		}
13418
+		if fieldNum <= 0 {
13419
+			return fmt.Errorf("proto: GetConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
13420
+		}
13421
+		switch fieldNum {
13422
+		case 1:
13423
+			if wireType != 2 {
13424
+				return fmt.Errorf("proto: wrong wireType = %d for field ConfigID", wireType)
13425
+			}
13426
+			var stringLen uint64
13427
+			for shift := uint(0); ; shift += 7 {
13428
+				if shift >= 64 {
13429
+					return ErrIntOverflowControl
13430
+				}
13431
+				if iNdEx >= l {
13432
+					return io.ErrUnexpectedEOF
13433
+				}
13434
+				b := dAtA[iNdEx]
13435
+				iNdEx++
13436
+				stringLen |= (uint64(b) & 0x7F) << shift
13437
+				if b < 0x80 {
13438
+					break
13439
+				}
13440
+			}
13441
+			intStringLen := int(stringLen)
13442
+			if intStringLen < 0 {
13443
+				return ErrInvalidLengthControl
13444
+			}
13445
+			postIndex := iNdEx + intStringLen
13446
+			if postIndex > l {
13447
+				return io.ErrUnexpectedEOF
13448
+			}
13449
+			m.ConfigID = string(dAtA[iNdEx:postIndex])
13450
+			iNdEx = postIndex
13451
+		default:
13452
+			iNdEx = preIndex
13453
+			skippy, err := skipControl(dAtA[iNdEx:])
13454
+			if err != nil {
13455
+				return err
13456
+			}
13457
+			if skippy < 0 {
13458
+				return ErrInvalidLengthControl
13459
+			}
13460
+			if (iNdEx + skippy) > l {
13461
+				return io.ErrUnexpectedEOF
13462
+			}
13463
+			iNdEx += skippy
13464
+		}
13465
+	}
13466
+
13467
+	if iNdEx > l {
13468
+		return io.ErrUnexpectedEOF
13469
+	}
13470
+	return nil
13471
+}
13472
+func (m *GetConfigResponse) Unmarshal(dAtA []byte) error {
13473
+	l := len(dAtA)
13474
+	iNdEx := 0
13475
+	for iNdEx < l {
13476
+		preIndex := iNdEx
13477
+		var wire uint64
13478
+		for shift := uint(0); ; shift += 7 {
13479
+			if shift >= 64 {
13480
+				return ErrIntOverflowControl
13481
+			}
13482
+			if iNdEx >= l {
13483
+				return io.ErrUnexpectedEOF
13484
+			}
13485
+			b := dAtA[iNdEx]
13486
+			iNdEx++
13487
+			wire |= (uint64(b) & 0x7F) << shift
13488
+			if b < 0x80 {
13489
+				break
13490
+			}
13491
+		}
13492
+		fieldNum := int32(wire >> 3)
13493
+		wireType := int(wire & 0x7)
13494
+		if wireType == 4 {
13495
+			return fmt.Errorf("proto: GetConfigResponse: wiretype end group for non-group")
13496
+		}
13497
+		if fieldNum <= 0 {
13498
+			return fmt.Errorf("proto: GetConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire)
13499
+		}
13500
+		switch fieldNum {
13501
+		case 1:
13502
+			if wireType != 2 {
13503
+				return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
13504
+			}
13505
+			var msglen int
13506
+			for shift := uint(0); ; shift += 7 {
13507
+				if shift >= 64 {
13508
+					return ErrIntOverflowControl
13509
+				}
13510
+				if iNdEx >= l {
13511
+					return io.ErrUnexpectedEOF
13512
+				}
13513
+				b := dAtA[iNdEx]
13514
+				iNdEx++
13515
+				msglen |= (int(b) & 0x7F) << shift
13516
+				if b < 0x80 {
13517
+					break
13518
+				}
13519
+			}
13520
+			if msglen < 0 {
13521
+				return ErrInvalidLengthControl
13522
+			}
13523
+			postIndex := iNdEx + msglen
13524
+			if postIndex > l {
13525
+				return io.ErrUnexpectedEOF
13526
+			}
13527
+			if m.Config == nil {
13528
+				m.Config = &Config{}
13529
+			}
13530
+			if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13531
+				return err
13532
+			}
13533
+			iNdEx = postIndex
13534
+		default:
13535
+			iNdEx = preIndex
13536
+			skippy, err := skipControl(dAtA[iNdEx:])
13537
+			if err != nil {
13538
+				return err
13539
+			}
13540
+			if skippy < 0 {
13541
+				return ErrInvalidLengthControl
13542
+			}
13543
+			if (iNdEx + skippy) > l {
13544
+				return io.ErrUnexpectedEOF
13545
+			}
13546
+			iNdEx += skippy
13547
+		}
13548
+	}
13549
+
13550
+	if iNdEx > l {
13551
+		return io.ErrUnexpectedEOF
13552
+	}
13553
+	return nil
13554
+}
13555
+func (m *UpdateConfigRequest) Unmarshal(dAtA []byte) error {
13556
+	l := len(dAtA)
13557
+	iNdEx := 0
13558
+	for iNdEx < l {
13559
+		preIndex := iNdEx
13560
+		var wire uint64
13561
+		for shift := uint(0); ; shift += 7 {
13562
+			if shift >= 64 {
13563
+				return ErrIntOverflowControl
13564
+			}
13565
+			if iNdEx >= l {
13566
+				return io.ErrUnexpectedEOF
13567
+			}
13568
+			b := dAtA[iNdEx]
13569
+			iNdEx++
13570
+			wire |= (uint64(b) & 0x7F) << shift
13571
+			if b < 0x80 {
13572
+				break
13573
+			}
13574
+		}
13575
+		fieldNum := int32(wire >> 3)
13576
+		wireType := int(wire & 0x7)
13577
+		if wireType == 4 {
13578
+			return fmt.Errorf("proto: UpdateConfigRequest: wiretype end group for non-group")
13579
+		}
13580
+		if fieldNum <= 0 {
13581
+			return fmt.Errorf("proto: UpdateConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
13582
+		}
13583
+		switch fieldNum {
13584
+		case 1:
13585
+			if wireType != 2 {
13586
+				return fmt.Errorf("proto: wrong wireType = %d for field ConfigID", wireType)
13587
+			}
13588
+			var stringLen uint64
13589
+			for shift := uint(0); ; shift += 7 {
13590
+				if shift >= 64 {
13591
+					return ErrIntOverflowControl
13592
+				}
13593
+				if iNdEx >= l {
13594
+					return io.ErrUnexpectedEOF
13595
+				}
13596
+				b := dAtA[iNdEx]
13597
+				iNdEx++
13598
+				stringLen |= (uint64(b) & 0x7F) << shift
13599
+				if b < 0x80 {
13600
+					break
13601
+				}
13602
+			}
13603
+			intStringLen := int(stringLen)
13604
+			if intStringLen < 0 {
13605
+				return ErrInvalidLengthControl
13606
+			}
13607
+			postIndex := iNdEx + intStringLen
13608
+			if postIndex > l {
13609
+				return io.ErrUnexpectedEOF
13610
+			}
13611
+			m.ConfigID = string(dAtA[iNdEx:postIndex])
13612
+			iNdEx = postIndex
13613
+		case 2:
13614
+			if wireType != 2 {
13615
+				return fmt.Errorf("proto: wrong wireType = %d for field ConfigVersion", wireType)
13616
+			}
13617
+			var msglen int
13618
+			for shift := uint(0); ; shift += 7 {
13619
+				if shift >= 64 {
13620
+					return ErrIntOverflowControl
13621
+				}
13622
+				if iNdEx >= l {
13623
+					return io.ErrUnexpectedEOF
13624
+				}
13625
+				b := dAtA[iNdEx]
13626
+				iNdEx++
13627
+				msglen |= (int(b) & 0x7F) << shift
13628
+				if b < 0x80 {
13629
+					break
13630
+				}
13631
+			}
13632
+			if msglen < 0 {
13633
+				return ErrInvalidLengthControl
13634
+			}
13635
+			postIndex := iNdEx + msglen
13636
+			if postIndex > l {
13637
+				return io.ErrUnexpectedEOF
13638
+			}
13639
+			if m.ConfigVersion == nil {
13640
+				m.ConfigVersion = &Version{}
13641
+			}
13642
+			if err := m.ConfigVersion.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13643
+				return err
13644
+			}
13645
+			iNdEx = postIndex
13646
+		case 3:
13647
+			if wireType != 2 {
13648
+				return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
13649
+			}
13650
+			var msglen int
13651
+			for shift := uint(0); ; shift += 7 {
13652
+				if shift >= 64 {
13653
+					return ErrIntOverflowControl
13654
+				}
13655
+				if iNdEx >= l {
13656
+					return io.ErrUnexpectedEOF
13657
+				}
13658
+				b := dAtA[iNdEx]
13659
+				iNdEx++
13660
+				msglen |= (int(b) & 0x7F) << shift
13661
+				if b < 0x80 {
13662
+					break
13663
+				}
13664
+			}
13665
+			if msglen < 0 {
13666
+				return ErrInvalidLengthControl
13667
+			}
13668
+			postIndex := iNdEx + msglen
13669
+			if postIndex > l {
13670
+				return io.ErrUnexpectedEOF
13671
+			}
13672
+			if m.Spec == nil {
13673
+				m.Spec = &ConfigSpec{}
13674
+			}
13675
+			if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13676
+				return err
13677
+			}
13678
+			iNdEx = postIndex
13679
+		default:
13680
+			iNdEx = preIndex
13681
+			skippy, err := skipControl(dAtA[iNdEx:])
13682
+			if err != nil {
13683
+				return err
13684
+			}
13685
+			if skippy < 0 {
13686
+				return ErrInvalidLengthControl
13687
+			}
13688
+			if (iNdEx + skippy) > l {
13689
+				return io.ErrUnexpectedEOF
13690
+			}
13691
+			iNdEx += skippy
13692
+		}
13693
+	}
13694
+
13695
+	if iNdEx > l {
13696
+		return io.ErrUnexpectedEOF
13697
+	}
13698
+	return nil
13699
+}
13700
+func (m *UpdateConfigResponse) Unmarshal(dAtA []byte) error {
13701
+	l := len(dAtA)
13702
+	iNdEx := 0
13703
+	for iNdEx < l {
13704
+		preIndex := iNdEx
13705
+		var wire uint64
13706
+		for shift := uint(0); ; shift += 7 {
13707
+			if shift >= 64 {
13708
+				return ErrIntOverflowControl
13709
+			}
13710
+			if iNdEx >= l {
13711
+				return io.ErrUnexpectedEOF
13712
+			}
13713
+			b := dAtA[iNdEx]
13714
+			iNdEx++
13715
+			wire |= (uint64(b) & 0x7F) << shift
13716
+			if b < 0x80 {
13717
+				break
13718
+			}
13719
+		}
13720
+		fieldNum := int32(wire >> 3)
13721
+		wireType := int(wire & 0x7)
13722
+		if wireType == 4 {
13723
+			return fmt.Errorf("proto: UpdateConfigResponse: wiretype end group for non-group")
13724
+		}
13725
+		if fieldNum <= 0 {
13726
+			return fmt.Errorf("proto: UpdateConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire)
13727
+		}
13728
+		switch fieldNum {
13729
+		case 1:
13730
+			if wireType != 2 {
13731
+				return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
13732
+			}
13733
+			var msglen int
13734
+			for shift := uint(0); ; shift += 7 {
13735
+				if shift >= 64 {
13736
+					return ErrIntOverflowControl
13737
+				}
13738
+				if iNdEx >= l {
13739
+					return io.ErrUnexpectedEOF
13740
+				}
13741
+				b := dAtA[iNdEx]
13742
+				iNdEx++
13743
+				msglen |= (int(b) & 0x7F) << shift
13744
+				if b < 0x80 {
13745
+					break
13746
+				}
13747
+			}
13748
+			if msglen < 0 {
13749
+				return ErrInvalidLengthControl
13750
+			}
13751
+			postIndex := iNdEx + msglen
13752
+			if postIndex > l {
13753
+				return io.ErrUnexpectedEOF
13754
+			}
13755
+			if m.Config == nil {
13756
+				m.Config = &Config{}
13757
+			}
13758
+			if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13759
+				return err
13760
+			}
13761
+			iNdEx = postIndex
13762
+		default:
13763
+			iNdEx = preIndex
13764
+			skippy, err := skipControl(dAtA[iNdEx:])
13765
+			if err != nil {
13766
+				return err
13767
+			}
13768
+			if skippy < 0 {
13769
+				return ErrInvalidLengthControl
13770
+			}
13771
+			if (iNdEx + skippy) > l {
13772
+				return io.ErrUnexpectedEOF
13773
+			}
13774
+			iNdEx += skippy
13775
+		}
13776
+	}
13777
+
13778
+	if iNdEx > l {
13779
+		return io.ErrUnexpectedEOF
13780
+	}
13781
+	return nil
13782
+}
13783
+func (m *ListConfigsRequest) Unmarshal(dAtA []byte) error {
13784
+	l := len(dAtA)
13785
+	iNdEx := 0
13786
+	for iNdEx < l {
13787
+		preIndex := iNdEx
13788
+		var wire uint64
13789
+		for shift := uint(0); ; shift += 7 {
13790
+			if shift >= 64 {
13791
+				return ErrIntOverflowControl
13792
+			}
13793
+			if iNdEx >= l {
13794
+				return io.ErrUnexpectedEOF
13795
+			}
13796
+			b := dAtA[iNdEx]
13797
+			iNdEx++
13798
+			wire |= (uint64(b) & 0x7F) << shift
13799
+			if b < 0x80 {
13800
+				break
13801
+			}
13802
+		}
13803
+		fieldNum := int32(wire >> 3)
13804
+		wireType := int(wire & 0x7)
13805
+		if wireType == 4 {
13806
+			return fmt.Errorf("proto: ListConfigsRequest: wiretype end group for non-group")
13807
+		}
13808
+		if fieldNum <= 0 {
13809
+			return fmt.Errorf("proto: ListConfigsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
13810
+		}
13811
+		switch fieldNum {
13812
+		case 1:
13813
+			if wireType != 2 {
13814
+				return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType)
13815
+			}
13816
+			var msglen int
13817
+			for shift := uint(0); ; shift += 7 {
13818
+				if shift >= 64 {
13819
+					return ErrIntOverflowControl
13820
+				}
13821
+				if iNdEx >= l {
13822
+					return io.ErrUnexpectedEOF
13823
+				}
13824
+				b := dAtA[iNdEx]
13825
+				iNdEx++
13826
+				msglen |= (int(b) & 0x7F) << shift
13827
+				if b < 0x80 {
13828
+					break
13829
+				}
13830
+			}
13831
+			if msglen < 0 {
13832
+				return ErrInvalidLengthControl
13833
+			}
13834
+			postIndex := iNdEx + msglen
13835
+			if postIndex > l {
13836
+				return io.ErrUnexpectedEOF
13837
+			}
13838
+			if m.Filters == nil {
13839
+				m.Filters = &ListConfigsRequest_Filters{}
13840
+			}
13841
+			if err := m.Filters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13842
+				return err
13843
+			}
13844
+			iNdEx = postIndex
13845
+		default:
13846
+			iNdEx = preIndex
13847
+			skippy, err := skipControl(dAtA[iNdEx:])
13848
+			if err != nil {
13849
+				return err
13850
+			}
13851
+			if skippy < 0 {
13852
+				return ErrInvalidLengthControl
13853
+			}
13854
+			if (iNdEx + skippy) > l {
13855
+				return io.ErrUnexpectedEOF
13856
+			}
13857
+			iNdEx += skippy
13858
+		}
13859
+	}
13860
+
13861
+	if iNdEx > l {
13862
+		return io.ErrUnexpectedEOF
13863
+	}
13864
+	return nil
13865
+}
13866
+func (m *ListConfigsRequest_Filters) Unmarshal(dAtA []byte) error {
13867
+	l := len(dAtA)
13868
+	iNdEx := 0
13869
+	for iNdEx < l {
13870
+		preIndex := iNdEx
13871
+		var wire uint64
13872
+		for shift := uint(0); ; shift += 7 {
13873
+			if shift >= 64 {
13874
+				return ErrIntOverflowControl
13875
+			}
13876
+			if iNdEx >= l {
13877
+				return io.ErrUnexpectedEOF
13878
+			}
13879
+			b := dAtA[iNdEx]
13880
+			iNdEx++
13881
+			wire |= (uint64(b) & 0x7F) << shift
13882
+			if b < 0x80 {
13883
+				break
13884
+			}
13885
+		}
13886
+		fieldNum := int32(wire >> 3)
13887
+		wireType := int(wire & 0x7)
13888
+		if wireType == 4 {
13889
+			return fmt.Errorf("proto: Filters: wiretype end group for non-group")
13890
+		}
13891
+		if fieldNum <= 0 {
13892
+			return fmt.Errorf("proto: Filters: illegal tag %d (wire type %d)", fieldNum, wire)
13893
+		}
13894
+		switch fieldNum {
13895
+		case 1:
13896
+			if wireType != 2 {
13897
+				return fmt.Errorf("proto: wrong wireType = %d for field Names", wireType)
13898
+			}
13899
+			var stringLen uint64
13900
+			for shift := uint(0); ; shift += 7 {
13901
+				if shift >= 64 {
13902
+					return ErrIntOverflowControl
13903
+				}
13904
+				if iNdEx >= l {
13905
+					return io.ErrUnexpectedEOF
13906
+				}
13907
+				b := dAtA[iNdEx]
13908
+				iNdEx++
13909
+				stringLen |= (uint64(b) & 0x7F) << shift
13910
+				if b < 0x80 {
13911
+					break
13912
+				}
13913
+			}
13914
+			intStringLen := int(stringLen)
13915
+			if intStringLen < 0 {
13916
+				return ErrInvalidLengthControl
13917
+			}
13918
+			postIndex := iNdEx + intStringLen
13919
+			if postIndex > l {
13920
+				return io.ErrUnexpectedEOF
13921
+			}
13922
+			m.Names = append(m.Names, string(dAtA[iNdEx:postIndex]))
13923
+			iNdEx = postIndex
13924
+		case 2:
13925
+			if wireType != 2 {
13926
+				return fmt.Errorf("proto: wrong wireType = %d for field IDPrefixes", wireType)
13927
+			}
13928
+			var stringLen uint64
13929
+			for shift := uint(0); ; shift += 7 {
13930
+				if shift >= 64 {
13931
+					return ErrIntOverflowControl
13932
+				}
13933
+				if iNdEx >= l {
13934
+					return io.ErrUnexpectedEOF
13935
+				}
13936
+				b := dAtA[iNdEx]
13937
+				iNdEx++
13938
+				stringLen |= (uint64(b) & 0x7F) << shift
13939
+				if b < 0x80 {
13940
+					break
13941
+				}
13942
+			}
13943
+			intStringLen := int(stringLen)
13944
+			if intStringLen < 0 {
13945
+				return ErrInvalidLengthControl
13946
+			}
13947
+			postIndex := iNdEx + intStringLen
13948
+			if postIndex > l {
13949
+				return io.ErrUnexpectedEOF
13950
+			}
13951
+			m.IDPrefixes = append(m.IDPrefixes, string(dAtA[iNdEx:postIndex]))
13952
+			iNdEx = postIndex
13953
+		case 3:
13954
+			if wireType != 2 {
13955
+				return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType)
13956
+			}
13957
+			var msglen int
13958
+			for shift := uint(0); ; shift += 7 {
13959
+				if shift >= 64 {
13960
+					return ErrIntOverflowControl
13961
+				}
13962
+				if iNdEx >= l {
13963
+					return io.ErrUnexpectedEOF
13964
+				}
13965
+				b := dAtA[iNdEx]
13966
+				iNdEx++
13967
+				msglen |= (int(b) & 0x7F) << shift
13968
+				if b < 0x80 {
13969
+					break
13970
+				}
13971
+			}
13972
+			if msglen < 0 {
13973
+				return ErrInvalidLengthControl
13974
+			}
13975
+			postIndex := iNdEx + msglen
13976
+			if postIndex > l {
13977
+				return io.ErrUnexpectedEOF
13978
+			}
13979
+			var keykey uint64
13980
+			for shift := uint(0); ; shift += 7 {
13981
+				if shift >= 64 {
13982
+					return ErrIntOverflowControl
13983
+				}
13984
+				if iNdEx >= l {
13985
+					return io.ErrUnexpectedEOF
13986
+				}
13987
+				b := dAtA[iNdEx]
13988
+				iNdEx++
13989
+				keykey |= (uint64(b) & 0x7F) << shift
13990
+				if b < 0x80 {
13991
+					break
13992
+				}
13993
+			}
13994
+			var stringLenmapkey uint64
13995
+			for shift := uint(0); ; shift += 7 {
13996
+				if shift >= 64 {
13997
+					return ErrIntOverflowControl
13998
+				}
13999
+				if iNdEx >= l {
14000
+					return io.ErrUnexpectedEOF
14001
+				}
14002
+				b := dAtA[iNdEx]
14003
+				iNdEx++
14004
+				stringLenmapkey |= (uint64(b) & 0x7F) << shift
14005
+				if b < 0x80 {
14006
+					break
14007
+				}
14008
+			}
14009
+			intStringLenmapkey := int(stringLenmapkey)
14010
+			if intStringLenmapkey < 0 {
14011
+				return ErrInvalidLengthControl
14012
+			}
14013
+			postStringIndexmapkey := iNdEx + intStringLenmapkey
14014
+			if postStringIndexmapkey > l {
14015
+				return io.ErrUnexpectedEOF
14016
+			}
14017
+			mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
14018
+			iNdEx = postStringIndexmapkey
14019
+			if m.Labels == nil {
14020
+				m.Labels = make(map[string]string)
14021
+			}
14022
+			if iNdEx < postIndex {
14023
+				var valuekey uint64
14024
+				for shift := uint(0); ; shift += 7 {
14025
+					if shift >= 64 {
14026
+						return ErrIntOverflowControl
14027
+					}
14028
+					if iNdEx >= l {
14029
+						return io.ErrUnexpectedEOF
14030
+					}
14031
+					b := dAtA[iNdEx]
14032
+					iNdEx++
14033
+					valuekey |= (uint64(b) & 0x7F) << shift
14034
+					if b < 0x80 {
14035
+						break
14036
+					}
14037
+				}
14038
+				var stringLenmapvalue uint64
14039
+				for shift := uint(0); ; shift += 7 {
14040
+					if shift >= 64 {
14041
+						return ErrIntOverflowControl
14042
+					}
14043
+					if iNdEx >= l {
14044
+						return io.ErrUnexpectedEOF
14045
+					}
14046
+					b := dAtA[iNdEx]
14047
+					iNdEx++
14048
+					stringLenmapvalue |= (uint64(b) & 0x7F) << shift
14049
+					if b < 0x80 {
14050
+						break
14051
+					}
14052
+				}
14053
+				intStringLenmapvalue := int(stringLenmapvalue)
14054
+				if intStringLenmapvalue < 0 {
14055
+					return ErrInvalidLengthControl
14056
+				}
14057
+				postStringIndexmapvalue := iNdEx + intStringLenmapvalue
14058
+				if postStringIndexmapvalue > l {
14059
+					return io.ErrUnexpectedEOF
14060
+				}
14061
+				mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue])
14062
+				iNdEx = postStringIndexmapvalue
14063
+				m.Labels[mapkey] = mapvalue
14064
+			} else {
14065
+				var mapvalue string
14066
+				m.Labels[mapkey] = mapvalue
14067
+			}
14068
+			iNdEx = postIndex
14069
+		case 4:
14070
+			if wireType != 2 {
14071
+				return fmt.Errorf("proto: wrong wireType = %d for field NamePrefixes", wireType)
14072
+			}
14073
+			var stringLen uint64
14074
+			for shift := uint(0); ; shift += 7 {
14075
+				if shift >= 64 {
14076
+					return ErrIntOverflowControl
14077
+				}
14078
+				if iNdEx >= l {
14079
+					return io.ErrUnexpectedEOF
14080
+				}
14081
+				b := dAtA[iNdEx]
14082
+				iNdEx++
14083
+				stringLen |= (uint64(b) & 0x7F) << shift
14084
+				if b < 0x80 {
14085
+					break
14086
+				}
14087
+			}
14088
+			intStringLen := int(stringLen)
14089
+			if intStringLen < 0 {
14090
+				return ErrInvalidLengthControl
14091
+			}
14092
+			postIndex := iNdEx + intStringLen
14093
+			if postIndex > l {
14094
+				return io.ErrUnexpectedEOF
14095
+			}
14096
+			m.NamePrefixes = append(m.NamePrefixes, string(dAtA[iNdEx:postIndex]))
14097
+			iNdEx = postIndex
14098
+		default:
14099
+			iNdEx = preIndex
14100
+			skippy, err := skipControl(dAtA[iNdEx:])
14101
+			if err != nil {
14102
+				return err
14103
+			}
14104
+			if skippy < 0 {
14105
+				return ErrInvalidLengthControl
14106
+			}
14107
+			if (iNdEx + skippy) > l {
14108
+				return io.ErrUnexpectedEOF
14109
+			}
14110
+			iNdEx += skippy
14111
+		}
14112
+	}
14113
+
14114
+	if iNdEx > l {
14115
+		return io.ErrUnexpectedEOF
14116
+	}
14117
+	return nil
14118
+}
14119
+func (m *ListConfigsResponse) Unmarshal(dAtA []byte) error {
14120
+	l := len(dAtA)
14121
+	iNdEx := 0
14122
+	for iNdEx < l {
14123
+		preIndex := iNdEx
14124
+		var wire uint64
14125
+		for shift := uint(0); ; shift += 7 {
14126
+			if shift >= 64 {
14127
+				return ErrIntOverflowControl
14128
+			}
14129
+			if iNdEx >= l {
14130
+				return io.ErrUnexpectedEOF
14131
+			}
14132
+			b := dAtA[iNdEx]
14133
+			iNdEx++
14134
+			wire |= (uint64(b) & 0x7F) << shift
14135
+			if b < 0x80 {
14136
+				break
14137
+			}
14138
+		}
14139
+		fieldNum := int32(wire >> 3)
14140
+		wireType := int(wire & 0x7)
14141
+		if wireType == 4 {
14142
+			return fmt.Errorf("proto: ListConfigsResponse: wiretype end group for non-group")
14143
+		}
14144
+		if fieldNum <= 0 {
14145
+			return fmt.Errorf("proto: ListConfigsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
14146
+		}
14147
+		switch fieldNum {
14148
+		case 1:
14149
+			if wireType != 2 {
14150
+				return fmt.Errorf("proto: wrong wireType = %d for field Configs", wireType)
14151
+			}
14152
+			var msglen int
14153
+			for shift := uint(0); ; shift += 7 {
14154
+				if shift >= 64 {
14155
+					return ErrIntOverflowControl
14156
+				}
14157
+				if iNdEx >= l {
14158
+					return io.ErrUnexpectedEOF
14159
+				}
14160
+				b := dAtA[iNdEx]
14161
+				iNdEx++
14162
+				msglen |= (int(b) & 0x7F) << shift
14163
+				if b < 0x80 {
14164
+					break
14165
+				}
14166
+			}
14167
+			if msglen < 0 {
14168
+				return ErrInvalidLengthControl
14169
+			}
14170
+			postIndex := iNdEx + msglen
14171
+			if postIndex > l {
14172
+				return io.ErrUnexpectedEOF
14173
+			}
14174
+			m.Configs = append(m.Configs, &Config{})
14175
+			if err := m.Configs[len(m.Configs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
14176
+				return err
14177
+			}
14178
+			iNdEx = postIndex
14179
+		default:
14180
+			iNdEx = preIndex
14181
+			skippy, err := skipControl(dAtA[iNdEx:])
14182
+			if err != nil {
14183
+				return err
14184
+			}
14185
+			if skippy < 0 {
14186
+				return ErrInvalidLengthControl
14187
+			}
14188
+			if (iNdEx + skippy) > l {
14189
+				return io.ErrUnexpectedEOF
14190
+			}
14191
+			iNdEx += skippy
14192
+		}
14193
+	}
14194
+
14195
+	if iNdEx > l {
14196
+		return io.ErrUnexpectedEOF
14197
+	}
14198
+	return nil
14199
+}
14200
+func (m *CreateConfigRequest) Unmarshal(dAtA []byte) error {
14201
+	l := len(dAtA)
14202
+	iNdEx := 0
14203
+	for iNdEx < l {
14204
+		preIndex := iNdEx
14205
+		var wire uint64
14206
+		for shift := uint(0); ; shift += 7 {
14207
+			if shift >= 64 {
14208
+				return ErrIntOverflowControl
14209
+			}
14210
+			if iNdEx >= l {
14211
+				return io.ErrUnexpectedEOF
14212
+			}
14213
+			b := dAtA[iNdEx]
14214
+			iNdEx++
14215
+			wire |= (uint64(b) & 0x7F) << shift
14216
+			if b < 0x80 {
14217
+				break
14218
+			}
14219
+		}
14220
+		fieldNum := int32(wire >> 3)
14221
+		wireType := int(wire & 0x7)
14222
+		if wireType == 4 {
14223
+			return fmt.Errorf("proto: CreateConfigRequest: wiretype end group for non-group")
14224
+		}
14225
+		if fieldNum <= 0 {
14226
+			return fmt.Errorf("proto: CreateConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
14227
+		}
14228
+		switch fieldNum {
14229
+		case 1:
14230
+			if wireType != 2 {
14231
+				return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
14232
+			}
14233
+			var msglen int
14234
+			for shift := uint(0); ; shift += 7 {
14235
+				if shift >= 64 {
14236
+					return ErrIntOverflowControl
14237
+				}
14238
+				if iNdEx >= l {
14239
+					return io.ErrUnexpectedEOF
14240
+				}
14241
+				b := dAtA[iNdEx]
14242
+				iNdEx++
14243
+				msglen |= (int(b) & 0x7F) << shift
14244
+				if b < 0x80 {
14245
+					break
14246
+				}
14247
+			}
14248
+			if msglen < 0 {
14249
+				return ErrInvalidLengthControl
14250
+			}
14251
+			postIndex := iNdEx + msglen
14252
+			if postIndex > l {
14253
+				return io.ErrUnexpectedEOF
14254
+			}
14255
+			if m.Spec == nil {
14256
+				m.Spec = &ConfigSpec{}
14257
+			}
14258
+			if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
14259
+				return err
14260
+			}
14261
+			iNdEx = postIndex
14262
+		default:
14263
+			iNdEx = preIndex
14264
+			skippy, err := skipControl(dAtA[iNdEx:])
14265
+			if err != nil {
14266
+				return err
14267
+			}
14268
+			if skippy < 0 {
14269
+				return ErrInvalidLengthControl
14270
+			}
14271
+			if (iNdEx + skippy) > l {
14272
+				return io.ErrUnexpectedEOF
14273
+			}
14274
+			iNdEx += skippy
14275
+		}
14276
+	}
14277
+
14278
+	if iNdEx > l {
14279
+		return io.ErrUnexpectedEOF
14280
+	}
14281
+	return nil
14282
+}
14283
+func (m *CreateConfigResponse) Unmarshal(dAtA []byte) error {
14284
+	l := len(dAtA)
14285
+	iNdEx := 0
14286
+	for iNdEx < l {
14287
+		preIndex := iNdEx
14288
+		var wire uint64
14289
+		for shift := uint(0); ; shift += 7 {
14290
+			if shift >= 64 {
14291
+				return ErrIntOverflowControl
14292
+			}
14293
+			if iNdEx >= l {
14294
+				return io.ErrUnexpectedEOF
14295
+			}
14296
+			b := dAtA[iNdEx]
14297
+			iNdEx++
14298
+			wire |= (uint64(b) & 0x7F) << shift
14299
+			if b < 0x80 {
14300
+				break
14301
+			}
14302
+		}
14303
+		fieldNum := int32(wire >> 3)
14304
+		wireType := int(wire & 0x7)
14305
+		if wireType == 4 {
14306
+			return fmt.Errorf("proto: CreateConfigResponse: wiretype end group for non-group")
14307
+		}
14308
+		if fieldNum <= 0 {
14309
+			return fmt.Errorf("proto: CreateConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire)
14310
+		}
14311
+		switch fieldNum {
14312
+		case 1:
14313
+			if wireType != 2 {
14314
+				return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
14315
+			}
14316
+			var msglen int
14317
+			for shift := uint(0); ; shift += 7 {
14318
+				if shift >= 64 {
14319
+					return ErrIntOverflowControl
14320
+				}
14321
+				if iNdEx >= l {
14322
+					return io.ErrUnexpectedEOF
14323
+				}
14324
+				b := dAtA[iNdEx]
14325
+				iNdEx++
14326
+				msglen |= (int(b) & 0x7F) << shift
14327
+				if b < 0x80 {
14328
+					break
14329
+				}
14330
+			}
14331
+			if msglen < 0 {
14332
+				return ErrInvalidLengthControl
14333
+			}
14334
+			postIndex := iNdEx + msglen
14335
+			if postIndex > l {
14336
+				return io.ErrUnexpectedEOF
14337
+			}
14338
+			if m.Config == nil {
14339
+				m.Config = &Config{}
14340
+			}
14341
+			if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
14342
+				return err
14343
+			}
14344
+			iNdEx = postIndex
14345
+		default:
14346
+			iNdEx = preIndex
14347
+			skippy, err := skipControl(dAtA[iNdEx:])
14348
+			if err != nil {
14349
+				return err
14350
+			}
14351
+			if skippy < 0 {
14352
+				return ErrInvalidLengthControl
14353
+			}
14354
+			if (iNdEx + skippy) > l {
14355
+				return io.ErrUnexpectedEOF
14356
+			}
14357
+			iNdEx += skippy
14358
+		}
14359
+	}
14360
+
14361
+	if iNdEx > l {
14362
+		return io.ErrUnexpectedEOF
14363
+	}
14364
+	return nil
14365
+}
14366
+func (m *RemoveConfigRequest) Unmarshal(dAtA []byte) error {
14367
+	l := len(dAtA)
14368
+	iNdEx := 0
14369
+	for iNdEx < l {
14370
+		preIndex := iNdEx
14371
+		var wire uint64
14372
+		for shift := uint(0); ; shift += 7 {
14373
+			if shift >= 64 {
14374
+				return ErrIntOverflowControl
14375
+			}
14376
+			if iNdEx >= l {
14377
+				return io.ErrUnexpectedEOF
14378
+			}
14379
+			b := dAtA[iNdEx]
14380
+			iNdEx++
14381
+			wire |= (uint64(b) & 0x7F) << shift
14382
+			if b < 0x80 {
14383
+				break
14384
+			}
14385
+		}
14386
+		fieldNum := int32(wire >> 3)
14387
+		wireType := int(wire & 0x7)
14388
+		if wireType == 4 {
14389
+			return fmt.Errorf("proto: RemoveConfigRequest: wiretype end group for non-group")
14390
+		}
14391
+		if fieldNum <= 0 {
14392
+			return fmt.Errorf("proto: RemoveConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
14393
+		}
14394
+		switch fieldNum {
14395
+		case 1:
14396
+			if wireType != 2 {
14397
+				return fmt.Errorf("proto: wrong wireType = %d for field ConfigID", wireType)
14398
+			}
14399
+			var stringLen uint64
14400
+			for shift := uint(0); ; shift += 7 {
14401
+				if shift >= 64 {
14402
+					return ErrIntOverflowControl
14403
+				}
14404
+				if iNdEx >= l {
14405
+					return io.ErrUnexpectedEOF
14406
+				}
14407
+				b := dAtA[iNdEx]
14408
+				iNdEx++
14409
+				stringLen |= (uint64(b) & 0x7F) << shift
14410
+				if b < 0x80 {
14411
+					break
14412
+				}
14413
+			}
14414
+			intStringLen := int(stringLen)
14415
+			if intStringLen < 0 {
14416
+				return ErrInvalidLengthControl
14417
+			}
14418
+			postIndex := iNdEx + intStringLen
14419
+			if postIndex > l {
14420
+				return io.ErrUnexpectedEOF
14421
+			}
14422
+			m.ConfigID = string(dAtA[iNdEx:postIndex])
14423
+			iNdEx = postIndex
14424
+		default:
14425
+			iNdEx = preIndex
14426
+			skippy, err := skipControl(dAtA[iNdEx:])
14427
+			if err != nil {
14428
+				return err
14429
+			}
14430
+			if skippy < 0 {
14431
+				return ErrInvalidLengthControl
14432
+			}
14433
+			if (iNdEx + skippy) > l {
14434
+				return io.ErrUnexpectedEOF
14435
+			}
14436
+			iNdEx += skippy
14437
+		}
14438
+	}
14439
+
14440
+	if iNdEx > l {
14441
+		return io.ErrUnexpectedEOF
14442
+	}
14443
+	return nil
14444
+}
14445
+func (m *RemoveConfigResponse) Unmarshal(dAtA []byte) error {
14446
+	l := len(dAtA)
14447
+	iNdEx := 0
14448
+	for iNdEx < l {
14449
+		preIndex := iNdEx
14450
+		var wire uint64
14451
+		for shift := uint(0); ; shift += 7 {
14452
+			if shift >= 64 {
14453
+				return ErrIntOverflowControl
14454
+			}
14455
+			if iNdEx >= l {
14456
+				return io.ErrUnexpectedEOF
14457
+			}
14458
+			b := dAtA[iNdEx]
14459
+			iNdEx++
14460
+			wire |= (uint64(b) & 0x7F) << shift
14461
+			if b < 0x80 {
14462
+				break
14463
+			}
14464
+		}
14465
+		fieldNum := int32(wire >> 3)
14466
+		wireType := int(wire & 0x7)
14467
+		if wireType == 4 {
14468
+			return fmt.Errorf("proto: RemoveConfigResponse: wiretype end group for non-group")
14469
+		}
14470
+		if fieldNum <= 0 {
14471
+			return fmt.Errorf("proto: RemoveConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire)
14472
+		}
14473
+		switch fieldNum {
14474
+		default:
14475
+			iNdEx = preIndex
14476
+			skippy, err := skipControl(dAtA[iNdEx:])
14477
+			if err != nil {
14478
+				return err
14479
+			}
14480
+			if skippy < 0 {
14481
+				return ErrInvalidLengthControl
14482
+			}
14483
+			if (iNdEx + skippy) > l {
14484
+				return io.ErrUnexpectedEOF
14485
+			}
14486
+			iNdEx += skippy
14487
+		}
14488
+	}
14489
+
14490
+	if iNdEx > l {
14491
+		return io.ErrUnexpectedEOF
14492
+	}
14493
+	return nil
14494
+}
13393 14495
 func skipControl(dAtA []byte) (n int, err error) {
13394 14496
 	l := len(dAtA)
13395 14497
 	iNdEx := 0
... ...
@@ -13498,125 +15992,136 @@ var (
13498 13498
 func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
13499 13499
 
13500 13500
 var fileDescriptorControl = []byte{
13501
-	// 1917 bytes of a gzipped FileDescriptorProto
13502
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x5a, 0x4f, 0x6f, 0x1b, 0x41,
13503
-	0x15, 0x8f, 0xff, 0x24, 0xb6, 0x9f, 0x63, 0x27, 0x99, 0xb8, 0xc5, 0x72, 0x4b, 0x12, 0x6d, 0x69,
13504
-	0xe2, 0xa0, 0xe0, 0x50, 0x97, 0x8a, 0x52, 0xc4, 0x9f, 0x26, 0x6e, 0x8b, 0x9b, 0x36, 0xad, 0x36,
13505
-	0x49, 0xc5, 0xcd, 0xda, 0xd8, 0x93, 0xb0, 0xb5, 0xe3, 0x35, 0xbb, 0xeb, 0xb4, 0x11, 0x17, 0x40,
13506
-	0xe5, 0x23, 0x20, 0x71, 0xe5, 0x0a, 0x12, 0x07, 0x4e, 0xfd, 0x08, 0x15, 0x27, 0x8e, 0x48, 0x48,
13507
-	0x11, 0xb5, 0x84, 0xc4, 0x89, 0xcf, 0x80, 0xe6, 0xdf, 0xee, 0x7a, 0x3d, 0xbb, 0x6b, 0x27, 0x96,
13508
-	0xc2, 0xa9, 0xde, 0xd9, 0xdf, 0x9b, 0xf7, 0x66, 0xde, 0x6f, 0x7e, 0xfb, 0xe6, 0xa5, 0x90, 0x6b,
13509
-	0x1a, 0x5d, 0xdb, 0x34, 0x3a, 0x95, 0x9e, 0x69, 0xd8, 0x06, 0x42, 0x2d, 0xa3, 0xd9, 0xc6, 0x66,
13510
-	0xc5, 0xfa, 0xa0, 0x99, 0x67, 0x6d, 0xdd, 0xae, 0x9c, 0x3f, 0x28, 0x65, 0xad, 0x1e, 0x6e, 0x5a,
13511
-	0x0c, 0x50, 0xca, 0x19, 0xc7, 0xef, 0x71, 0xd3, 0x16, 0x8f, 0x59, 0xfb, 0xa2, 0x87, 0xc5, 0x43,
13512
-	0xe1, 0xd4, 0x38, 0x35, 0xe8, 0xcf, 0x6d, 0xf2, 0x8b, 0x8f, 0x2e, 0xf7, 0x3a, 0xfd, 0x53, 0xbd,
13513
-	0xbb, 0xcd, 0xfe, 0x61, 0x83, 0xca, 0x23, 0xc8, 0xbf, 0xc0, 0xf6, 0xbe, 0xd1, 0xc2, 0x2a, 0xfe,
13514
-	0x65, 0x1f, 0x5b, 0x36, 0xba, 0x07, 0xa9, 0xae, 0xd1, 0xc2, 0x0d, 0xbd, 0x55, 0x8c, 0xad, 0xc5,
13515
-	0xca, 0x99, 0x1d, 0x18, 0x5c, 0xae, 0xce, 0x11, 0x44, 0xbd, 0xa6, 0xce, 0x91, 0x57, 0xf5, 0x96,
13516
-	0xf2, 0x13, 0x58, 0x70, 0xcc, 0xac, 0x9e, 0xd1, 0xb5, 0x30, 0xda, 0x82, 0x24, 0x79, 0x49, 0x8d,
13517
-	0xb2, 0xd5, 0x62, 0x65, 0x74, 0x01, 0x15, 0x8a, 0xa7, 0x28, 0xe5, 0x32, 0x01, 0x8b, 0xaf, 0x74,
13518
-	0x8b, 0x4e, 0x61, 0x09, 0xd7, 0xcf, 0x21, 0x75, 0xa2, 0x77, 0x6c, 0x6c, 0x5a, 0x7c, 0x96, 0x2d,
13519
-	0xd9, 0x2c, 0x7e, 0xb3, 0xca, 0x73, 0x66, 0xa3, 0x0a, 0xe3, 0xd2, 0x6f, 0x12, 0x90, 0xe2, 0x83,
13520
-	0xa8, 0x00, 0xb3, 0x5d, 0xed, 0x0c, 0x93, 0x19, 0x13, 0xe5, 0x8c, 0xca, 0x1e, 0xd0, 0x36, 0x64,
13521
-	0xf5, 0x56, 0xa3, 0x67, 0xe2, 0x13, 0xfd, 0x23, 0xb6, 0x8a, 0x71, 0xf2, 0x6e, 0x27, 0x3f, 0xb8,
13522
-	0x5c, 0x85, 0x7a, 0xed, 0x2d, 0x1f, 0x55, 0x41, 0x6f, 0x89, 0xdf, 0xe8, 0x2d, 0xcc, 0x75, 0xb4,
13523
-	0x63, 0xdc, 0xb1, 0x8a, 0x89, 0xb5, 0x44, 0x39, 0x5b, 0x7d, 0x3c, 0x49, 0x64, 0x95, 0x57, 0xd4,
13524
-	0xf4, 0x59, 0xd7, 0x36, 0x2f, 0x54, 0x3e, 0x0f, 0xaa, 0x43, 0xf6, 0x0c, 0x9f, 0x1d, 0x63, 0xd3,
13525
-	0xfa, 0x85, 0xde, 0xb3, 0x8a, 0xc9, 0xb5, 0x44, 0x39, 0x5f, 0xdd, 0x08, 0xda, 0xb6, 0x83, 0x1e,
13526
-	0x6e, 0x56, 0x5e, 0x3b, 0x78, 0xd5, 0x6b, 0x8b, 0xaa, 0x30, 0x6b, 0x1a, 0x1d, 0x6c, 0x15, 0x67,
13527
-	0xe9, 0x24, 0x77, 0x03, 0xf7, 0xde, 0xe8, 0x60, 0x95, 0x41, 0xd1, 0x3d, 0xc8, 0x91, 0xad, 0x70,
13528
-	0xf7, 0x60, 0x8e, 0xee, 0xcf, 0x3c, 0x19, 0x14, 0xab, 0x2e, 0xfd, 0x00, 0xb2, 0x9e, 0xd0, 0xd1,
13529
-	0x22, 0x24, 0xda, 0xf8, 0x82, 0xd1, 0x42, 0x25, 0x3f, 0xc9, 0xee, 0x9e, 0x6b, 0x9d, 0x3e, 0x2e,
13530
-	0xc6, 0xe9, 0x18, 0x7b, 0x78, 0x12, 0x7f, 0x1c, 0x53, 0x76, 0x61, 0xc9, 0xb3, 0x1d, 0x9c, 0x23,
13531
-	0x15, 0x98, 0x25, 0xd9, 0x67, 0xc9, 0x08, 0x23, 0x09, 0x83, 0x29, 0x7f, 0x8a, 0xc1, 0xd2, 0x51,
13532
-	0xaf, 0xa5, 0xd9, 0x78, 0x52, 0x86, 0xa2, 0x1f, 0xc3, 0x3c, 0x05, 0x9d, 0x63, 0xd3, 0xd2, 0x8d,
13533
-	0x2e, 0x0d, 0x30, 0x5b, 0xbd, 0x23, 0xf3, 0xf8, 0x8e, 0x41, 0xd4, 0x2c, 0x31, 0xe0, 0x0f, 0xe8,
13534
-	0xbb, 0x90, 0x24, 0xc7, 0xad, 0x98, 0xa0, 0x76, 0x77, 0xc3, 0xf2, 0xa2, 0x52, 0xa4, 0xb2, 0x03,
13535
-	0xc8, 0x1b, 0xeb, 0x95, 0x8e, 0xc5, 0x3e, 0x2c, 0xa9, 0xf8, 0xcc, 0x38, 0x9f, 0x7c, 0xbd, 0x05,
13536
-	0x98, 0x3d, 0x31, 0xcc, 0x26, 0xcb, 0x44, 0x5a, 0x65, 0x0f, 0x4a, 0x01, 0x90, 0x77, 0x3e, 0x16,
13537
-	0x13, 0x3f, 0xf4, 0x87, 0x9a, 0xd5, 0xf6, 0xb8, 0xb0, 0x35, 0xab, 0xed, 0x73, 0x41, 0x10, 0xc4,
13538
-	0x05, 0x79, 0xe5, 0x1c, 0x7a, 0x66, 0xe6, 0xae, 0x8e, 0xbc, 0x0c, 0x5b, 0x1d, 0xc5, 0x53, 0x94,
13539
-	0xf2, 0x58, 0xac, 0x6e, 0x62, 0xd7, 0xce, 0x3a, 0xbc, 0xde, 0x95, 0xcf, 0x49, 0x26, 0x22, 0x64,
13540
-	0xf0, 0x0a, 0x22, 0xe2, 0x35, 0x1b, 0x15, 0x91, 0x7f, 0xde, 0xa0, 0x88, 0xc8, 0x22, 0x93, 0x8a,
13541
-	0xc8, 0x36, 0x64, 0x2d, 0x6c, 0x9e, 0xeb, 0x4d, 0xc2, 0x0e, 0x26, 0x22, 0x3c, 0x84, 0x03, 0x36,
13542
-	0x5c, 0xaf, 0x59, 0x2a, 0x70, 0x48, 0xbd, 0x65, 0xa1, 0x75, 0x48, 0x73, 0x2e, 0x31, 0xb5, 0xc8,
13543
-	0xec, 0x64, 0x07, 0x97, 0xab, 0x29, 0x46, 0x26, 0x4b, 0x4d, 0x31, 0x36, 0x59, 0xa8, 0x06, 0xf9,
13544
-	0x16, 0xb6, 0x74, 0x13, 0xb7, 0x1a, 0x96, 0xad, 0xd9, 0x5c, 0x1f, 0xf2, 0xd5, 0x6f, 0x06, 0xa5,
13545
-	0xf8, 0x80, 0xa0, 0xd4, 0x1c, 0x37, 0xa2, 0x4f, 0x12, 0x91, 0x49, 0x8d, 0x8a, 0x0c, 0xba, 0x0b,
13546
-	0xd0, 0xef, 0x35, 0x6c, 0xa3, 0x41, 0xce, 0x4e, 0x31, 0x4d, 0xe9, 0x9b, 0xee, 0xf7, 0x0e, 0x8d,
13547
-	0x9a, 0x66, 0x63, 0x54, 0x82, 0xb4, 0xd9, 0xef, 0xda, 0x3a, 0xd9, 0xfd, 0x0c, 0xb5, 0x76, 0x9e,
13548
-	0xa7, 0x20, 0x4f, 0x7c, 0xa3, 0x5d, 0x79, 0x22, 0x7c, 0x0b, 0x95, 0x27, 0x4a, 0x40, 0x06, 0x53,
13549
-	0xf6, 0xa0, 0xb0, 0x6b, 0x62, 0xcd, 0xc6, 0x7c, 0xb3, 0x05, 0x05, 0x1f, 0x72, 0xed, 0x60, 0xfc,
13550
-	0x5b, 0x95, 0x4d, 0xc3, 0x2d, 0x3c, 0xf2, 0xb1, 0x0f, 0xb7, 0x7c, 0x93, 0xf1, 0xa8, 0x1e, 0x41,
13551
-	0x8a, 0x27, 0x90, 0x4f, 0x78, 0x27, 0x64, 0x42, 0x55, 0x60, 0x95, 0xf7, 0xb0, 0xf4, 0x02, 0xdb,
13552
-	0xbe, 0xc8, 0xb6, 0x00, 0x5c, 0xbe, 0xf0, 0xf3, 0x96, 0x1b, 0x5c, 0xae, 0x66, 0x1c, 0xba, 0xa8,
13553
-	0x19, 0x87, 0x2d, 0x68, 0x03, 0x16, 0xf4, 0xae, 0x85, 0x4d, 0xbb, 0xd1, 0xc2, 0x27, 0x5a, 0xbf,
13554
-	0x63, 0x5b, 0x5c, 0x5d, 0xf2, 0x6c, 0xb8, 0xc6, 0x47, 0x95, 0x3d, 0x40, 0x5e, 0x5f, 0xd7, 0x0b,
13555
-	0xfc, 0xaf, 0x71, 0x28, 0x30, 0x21, 0xbd, 0x56, 0xf0, 0x35, 0x58, 0x10, 0xe8, 0x09, 0xbe, 0x01,
13556
-	0x79, 0x6e, 0x23, 0x3e, 0x03, 0x0f, 0x87, 0x3e, 0x03, 0xe3, 0xa5, 0x12, 0xbd, 0x86, 0xb4, 0x69,
13557
-	0x74, 0x3a, 0xc7, 0x5a, 0xb3, 0x5d, 0x4c, 0xae, 0xc5, 0xca, 0xf9, 0xea, 0x03, 0x99, 0xa1, 0x6c,
13558
-	0x91, 0x15, 0x95, 0x1b, 0xaa, 0xce, 0x14, 0x8a, 0x02, 0x69, 0x31, 0x8a, 0xd2, 0x90, 0xdc, 0x7f,
13559
-	0xb3, 0xff, 0x6c, 0x71, 0x06, 0xcd, 0x43, 0xfa, 0xad, 0xfa, 0xec, 0x5d, 0xfd, 0xcd, 0xd1, 0xc1,
13560
-	0x62, 0x8c, 0xb0, 0xc7, 0x37, 0xdd, 0xf5, 0x92, 0x50, 0x83, 0x02, 0x13, 0xdc, 0xeb, 0xe4, 0x40,
13561
-	0xf9, 0x06, 0xdc, 0xf2, 0xcd, 0xc2, 0x95, 0xfb, 0x53, 0x02, 0x96, 0xc9, 0xf9, 0xe3, 0xe3, 0x8e,
13562
-	0x78, 0xd7, 0xfd, 0xe2, 0xbd, 0x1d, 0x24, 0x91, 0x3e, 0xcb, 0x51, 0xfd, 0xfe, 0x63, 0x7c, 0xea,
13563
-	0xfa, 0x7d, 0xe0, 0xd3, 0xef, 0x1f, 0x4e, 0x18, 0x9c, 0x54, 0xc2, 0x47, 0x34, 0x32, 0x29, 0xd1,
13564
-	0x48, 0xaf, 0x0a, 0xce, 0x4e, 0x4f, 0x05, 0xdf, 0x40, 0x61, 0x38, 0x5c, 0x4e, 0x9a, 0xef, 0x43,
13565
-	0x9a, 0x27, 0x51, 0x68, 0x61, 0x28, 0x6b, 0x1c, 0xb0, 0xab, 0x88, 0xfb, 0xd8, 0xfe, 0x60, 0x98,
13566
-	0xed, 0x09, 0x14, 0x91, 0x5b, 0xc8, 0x14, 0xd1, 0x99, 0xcc, 0xe5, 0x74, 0x97, 0x0d, 0x85, 0x71,
13567
-	0x5a, 0x58, 0x09, 0xac, 0x72, 0x44, 0x15, 0xd1, 0x17, 0x19, 0x82, 0x24, 0xd9, 0x69, 0xbe, 0x5f,
13568
-	0xf4, 0x37, 0x21, 0x39, 0xb7, 0x21, 0x24, 0x8f, 0xbb, 0x24, 0xe7, 0xb6, 0x84, 0xe4, 0x1c, 0x50,
13569
-	0x6f, 0x71, 0xf1, 0x9b, 0x52, 0x8c, 0x3f, 0x17, 0xe7, 0x6e, 0xea, 0x61, 0x3a, 0x67, 0xd1, 0x17,
13570
-	0xa9, 0xf2, 0x9f, 0x38, 0x3b, 0x8b, 0x7c, 0xfc, 0x0a, 0x67, 0xd1, 0x67, 0x39, 0x7a, 0x16, 0x7f,
13571
-	0x77, 0x83, 0x67, 0x31, 0x20, 0xb8, 0x2b, 0x9f, 0xc5, 0x29, 0x9c, 0x37, 0x37, 0x24, 0xf7, 0xbc,
13572
-	0xf1, 0x44, 0x85, 0x9e, 0x37, 0x91, 0x39, 0x07, 0xac, 0x3c, 0xa5, 0x94, 0xde, 0xed, 0xf4, 0x2d,
13573
-	0x1b, 0x9b, 0x1e, 0x8d, 0x6e, 0xb2, 0x11, 0x9f, 0x46, 0x73, 0x1c, 0xe1, 0x05, 0x07, 0x38, 0xf4,
13574
-	0x75, 0xa6, 0x70, 0xe9, 0xcb, 0x21, 0x61, 0xf4, 0x15, 0x56, 0x02, 0xeb, 0x70, 0x89, 0xbf, 0xb8,
13575
-	0x02, 0x97, 0x7c, 0x96, 0xff, 0x5f, 0x5c, 0x0a, 0x08, 0xee, 0x26, 0xb9, 0xe4, 0x86, 0xe4, 0x72,
13576
-	0x89, 0x67, 0x23, 0x94, 0x4b, 0x22, 0x75, 0x0e, 0x58, 0xf9, 0x7d, 0x0c, 0xb2, 0x7b, 0xf8, 0x42,
13577
-	0x35, 0x6c, 0xcd, 0x26, 0xa5, 0xcf, 0xb7, 0x61, 0x89, 0x90, 0x0c, 0x9b, 0x8d, 0xf7, 0x86, 0xde,
13578
-	0x6d, 0xd8, 0x46, 0x1b, 0x77, 0x69, 0x68, 0x69, 0x75, 0x81, 0xbd, 0x78, 0x69, 0xe8, 0xdd, 0x43,
13579
-	0x32, 0x8c, 0xb6, 0x00, 0x9d, 0x69, 0x5d, 0xed, 0x74, 0x18, 0xcc, 0x8a, 0xc5, 0x45, 0xfe, 0x46,
13580
-	0x8a, 0xee, 0x77, 0x3b, 0x46, 0xb3, 0xdd, 0x20, 0xab, 0x4e, 0x0c, 0xa1, 0x8f, 0xe8, 0x8b, 0x3d,
13581
-	0x7c, 0xa1, 0xfc, 0xd6, 0xa9, 0x07, 0xaf, 0xc3, 0x73, 0x52, 0x0f, 0x0a, 0xf4, 0x24, 0xf5, 0x20,
13582
-	0xb7, 0x99, 0xa0, 0x1e, 0xe4, 0xde, 0x3d, 0xf5, 0xe0, 0x53, 0x52, 0x0f, 0xb2, 0x5d, 0xa5, 0xf5,
13583
-	0x60, 0x80, 0xa1, 0x67, 0xf3, 0x77, 0x92, 0x5f, 0x2e, 0x57, 0x67, 0x54, 0xc7, 0xcc, 0xad, 0xef,
13584
-	0xa6, 0x74, 0x50, 0x7f, 0x04, 0x8b, 0xb4, 0x62, 0x6f, 0x9a, 0xd8, 0x16, 0xfb, 0xb9, 0x09, 0x19,
13585
-	0x8b, 0x0e, 0xb8, 0xdb, 0x39, 0x3f, 0xb8, 0x5c, 0x4d, 0x33, 0x54, 0xbd, 0x46, 0xbe, 0xf3, 0xf4,
13586
-	0x57, 0x4b, 0x79, 0xc1, 0x2f, 0x17, 0xcc, 0x9c, 0x87, 0x52, 0x85, 0x39, 0x06, 0xe0, 0x91, 0x94,
13587
-	0xe4, 0x35, 0x03, 0xb5, 0xe1, 0x48, 0xe5, 0x73, 0x0c, 0x96, 0x45, 0xe1, 0x7a, 0xb5, 0x58, 0xd0,
13588
-	0x0e, 0xe4, 0x39, 0x74, 0x82, 0xbc, 0xe6, 0x98, 0x89, 0x48, 0x6b, 0x75, 0x28, 0xad, 0x2b, 0xc1,
13589
-	0x81, 0x7b, 0xca, 0x93, 0x97, 0xee, 0x35, 0xe5, 0xda, 0xdb, 0xf0, 0xef, 0x38, 0x20, 0x56, 0x89,
13590
-	0x91, 0x47, 0x47, 0x36, 0x7f, 0xe6, 0x97, 0xcd, 0x4a, 0x70, 0xc5, 0xe9, 0x35, 0x1c, 0x55, 0xcd,
13591
-	0x4f, 0xd3, 0x57, 0x4d, 0xd5, 0xa7, 0x9a, 0x4f, 0x26, 0x8b, 0xed, 0x46, 0x44, 0x73, 0x4f, 0x5c,
13592
-	0x3b, 0x78, 0x44, 0x3c, 0x65, 0xdf, 0x23, 0x97, 0x24, 0x3a, 0xc4, 0x25, 0x33, 0x2c, 0x67, 0x02,
13593
-	0xaa, 0xd4, 0x61, 0x59, 0xdc, 0xd8, 0xbd, 0xd4, 0xad, 0x0e, 0xd5, 0xba, 0x63, 0x73, 0x69, 0x78,
13594
-	0xaa, 0x6b, 0x70, 0xe9, 0xa7, 0xb0, 0x2c, 0x2e, 0x5d, 0x57, 0x3c, 0xdd, 0xb7, 0xdd, 0xcb, 0x9f,
13595
-	0x37, 0x9a, 0xea, 0x9f, 0x6f, 0x43, 0x6a, 0x97, 0xfd, 0x99, 0x02, 0xe9, 0x90, 0xe2, 0x7f, 0x01,
13596
-	0x40, 0x8a, 0x2c, 0xa8, 0xe1, 0xbf, 0x2a, 0x94, 0xee, 0x85, 0x62, 0x78, 0x25, 0x7a, 0xeb, 0x6f,
13597
-	0x7f, 0xf9, 0xef, 0x1f, 0xe2, 0x0b, 0x90, 0xa3, 0xa0, 0xef, 0xf0, 0x2f, 0x01, 0x32, 0x20, 0xe3,
13598
-	0xb4, 0x92, 0xd1, 0xb7, 0xc6, 0x69, 0xbc, 0x97, 0xee, 0x47, 0xa0, 0xc2, 0x1d, 0x9a, 0x00, 0x6e,
13599
-	0x27, 0x17, 0xdd, 0x0f, 0xbe, 0xbb, 0x7b, 0x57, 0xb8, 0x1e, 0x05, 0x8b, 0xf4, 0xe9, 0x76, 0x6a,
13600
-	0xe5, 0x3e, 0x47, 0x3a, 0xc3, 0x72, 0x9f, 0x92, 0x86, 0x6f, 0x80, 0x4f, 0x96, 0xc3, 0x43, 0xcd,
13601
-	0x6a, 0x07, 0xe6, 0xd0, 0xd3, 0xa9, 0x0d, 0xcc, 0xe1, 0x50, 0x4f, 0x36, 0x3c, 0x87, 0xb4, 0xdf,
13602
-	0x16, 0x9c, 0x43, 0x6f, 0xdf, 0x33, 0x38, 0x87, 0x43, 0x4d, 0xbb, 0xc8, 0xfd, 0xa4, 0xcb, 0x0b,
13603
-	0xd9, 0x4f, 0xef, 0x0a, 0xd7, 0xa3, 0x60, 0x91, 0x3e, 0xdd, 0x36, 0x98, 0xdc, 0xe7, 0x48, 0x4b,
13604
-	0x4e, 0xee, 0x73, 0xb4, 0x9b, 0x16, 0xe4, 0xf3, 0x23, 0xcc, 0x7b, 0xaf, 0xf0, 0x68, 0x63, 0xcc,
13605
-	0x9e, 0x44, 0xa9, 0x1c, 0x0d, 0x0c, 0xf7, 0xfc, 0x2b, 0xc8, 0x0d, 0x35, 0x2c, 0x91, 0x74, 0x46,
13606
-	0x59, 0x83, 0xb4, 0xb4, 0x39, 0x06, 0x32, 0xd2, 0xf9, 0x50, 0xbf, 0x4b, 0xee, 0x5c, 0xd6, 0x61,
13607
-	0x93, 0x3b, 0x97, 0x36, 0xcf, 0x42, 0x9c, 0x0f, 0xb5, 0xb5, 0xe4, 0xce, 0x65, 0xfd, 0x33, 0xb9,
13608
-	0x73, 0x79, 0x8f, 0x2c, 0x94, 0x64, 0xfc, 0x2a, 0x18, 0x48, 0xb2, 0xe1, 0xf6, 0x41, 0x20, 0xc9,
13609
-	0xfc, 0xbd, 0x80, 0x70, 0x92, 0x89, 0x7b, 0x6b, 0x30, 0xc9, 0x7c, 0x97, 0xed, 0x60, 0x92, 0xf9,
13610
-	0xaf, 0xc0, 0x91, 0x24, 0x13, 0x0b, 0x0e, 0x21, 0x99, 0x6f, 0xcd, 0x9b, 0x63, 0x20, 0xc7, 0xcc,
13611
-	0x73, 0xa8, 0x73, 0x59, 0xbf, 0x26, 0x2c, 0xcf, 0x63, 0x3a, 0x67, 0x79, 0xe6, 0x85, 0x7b, 0x60,
13612
-	0x9e, 0x87, 0xaf, 0x44, 0x81, 0x79, 0xf6, 0xdd, 0x1a, 0x22, 0xf2, 0x2c, 0xee, 0x94, 0xc1, 0x79,
13613
-	0xf6, 0x5d, 0x84, 0x83, 0xf3, 0xec, 0xbf, 0x9e, 0x46, 0x9e, 0x67, 0xb1, 0xe0, 0x90, 0xf3, 0xec,
13614
-	0x5b, 0xf3, 0xe6, 0x18, 0xc8, 0xc8, 0x8f, 0x93, 0x73, 0x9b, 0x91, 0x7f, 0x9c, 0xfc, 0x77, 0xa5,
13615
-	0xd2, 0xfd, 0x08, 0x54, 0xe4, 0x3e, 0x7b, 0xaf, 0x0e, 0xf2, 0x7d, 0x96, 0x5c, 0x8b, 0x4a, 0xe5,
13616
-	0x68, 0x60, 0xb8, 0xe7, 0x3e, 0x64, 0x3d, 0x05, 0x30, 0x5a, 0x1f, 0xaf, 0x66, 0x2f, 0x6d, 0x44,
13617
-	0xe2, 0x22, 0x17, 0xec, 0xad, 0x6f, 0xe5, 0x0b, 0x96, 0x14, 0xd3, 0xa5, 0x72, 0x34, 0x30, 0xd2,
13618
-	0xb3, 0xb7, 0x96, 0x95, 0x7b, 0x96, 0xd4, 0xcb, 0xa5, 0x72, 0x34, 0x30, 0xd4, 0xf3, 0x4e, 0xf1,
13619
-	0xcb, 0xd7, 0x95, 0x99, 0x7f, 0x7c, 0x5d, 0x99, 0xf9, 0xf5, 0x60, 0x25, 0xf6, 0x65, 0xb0, 0x12,
13620
-	0xfb, 0xfb, 0x60, 0x25, 0xf6, 0xaf, 0xc1, 0x4a, 0xec, 0x78, 0x8e, 0xfe, 0xdf, 0x9b, 0x87, 0xff,
13621
-	0x0b, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x09, 0x33, 0xa6, 0xf4, 0x23, 0x00, 0x00,
13501
+	// 2096 bytes of a gzipped FileDescriptorProto
13502
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x5a, 0x4b, 0x6f, 0x1b, 0xc9,
13503
+	0x11, 0x36, 0x1f, 0x12, 0xa9, 0xa2, 0x44, 0x49, 0x2d, 0x39, 0x21, 0x68, 0x47, 0x32, 0xc6, 0xb1,
13504
+	0x4d, 0x07, 0x0e, 0x95, 0xa5, 0xb3, 0x88, 0xb3, 0x41, 0x1e, 0x2b, 0xd1, 0xeb, 0x70, 0xb5, 0x2b,
13505
+	0x1b, 0x23, 0x6b, 0x91, 0x1b, 0x41, 0x91, 0x2d, 0x65, 0x4c, 0x8a, 0xc3, 0xcc, 0x0c, 0xb5, 0x2b,
13506
+	0xe4, 0x92, 0x0d, 0x36, 0x3f, 0x21, 0x40, 0xae, 0xb9, 0xe6, 0x90, 0x43, 0x4e, 0xfb, 0x13, 0x8c,
13507
+	0x9c, 0x72, 0x0c, 0x10, 0x40, 0xc8, 0x12, 0x08, 0x90, 0x53, 0x7e, 0x43, 0xd0, 0xdd, 0xd5, 0xf3,
13508
+	0x62, 0xcf, 0x0c, 0x5f, 0x80, 0x7c, 0x12, 0xa7, 0xe7, 0xab, 0xae, 0xea, 0xae, 0xaf, 0xbf, 0xe9,
13509
+	0xae, 0x16, 0xac, 0xb5, 0xcd, 0xbe, 0x63, 0x99, 0xbd, 0xea, 0xc0, 0x32, 0x1d, 0x93, 0x90, 0x8e,
13510
+	0xd9, 0xee, 0x52, 0xab, 0x6a, 0x7f, 0xde, 0xb2, 0x2e, 0xba, 0x86, 0x53, 0xbd, 0x7c, 0xaf, 0x5c,
13511
+	0xb0, 0x07, 0xb4, 0x6d, 0x0b, 0x40, 0x79, 0xcd, 0x3c, 0x7d, 0x43, 0xdb, 0x8e, 0x7c, 0x2c, 0x38,
13512
+	0x57, 0x03, 0x2a, 0x1f, 0xb6, 0xcf, 0xcd, 0x73, 0x93, 0xff, 0xdc, 0x63, 0xbf, 0xb0, 0x75, 0x6b,
13513
+	0xd0, 0x1b, 0x9e, 0x1b, 0xfd, 0x3d, 0xf1, 0x47, 0x34, 0x6a, 0xef, 0x43, 0xf1, 0x05, 0x75, 0x8e,
13514
+	0xcc, 0x0e, 0xd5, 0xe9, 0x6f, 0x86, 0xd4, 0x76, 0xc8, 0x7d, 0xc8, 0xf5, 0xcd, 0x0e, 0x6d, 0x1a,
13515
+	0x9d, 0x52, 0xea, 0x5e, 0xaa, 0xb2, 0xb2, 0x0f, 0xa3, 0xeb, 0xdd, 0x65, 0x86, 0x68, 0xd4, 0xf5,
13516
+	0x65, 0xf6, 0xaa, 0xd1, 0xd1, 0x7e, 0x0e, 0xeb, 0xae, 0x99, 0x3d, 0x30, 0xfb, 0x36, 0x25, 0x4f,
13517
+	0x20, 0xcb, 0x5e, 0x72, 0xa3, 0x42, 0xad, 0x54, 0x1d, 0x1f, 0x40, 0x95, 0xe3, 0x39, 0x4a, 0xbb,
13518
+	0xce, 0xc0, 0xc6, 0x27, 0x86, 0xcd, 0xbb, 0xb0, 0xa5, 0xeb, 0x8f, 0x20, 0x77, 0x66, 0xf4, 0x1c,
13519
+	0x6a, 0xd9, 0xd8, 0xcb, 0x13, 0x55, 0x2f, 0x61, 0xb3, 0xea, 0x47, 0xc2, 0x46, 0x97, 0xc6, 0xe5,
13520
+	0x2f, 0x33, 0x90, 0xc3, 0x46, 0xb2, 0x0d, 0x4b, 0xfd, 0xd6, 0x05, 0x65, 0x3d, 0x66, 0x2a, 0x2b,
13521
+	0xba, 0x78, 0x20, 0x7b, 0x50, 0x30, 0x3a, 0xcd, 0x81, 0x45, 0xcf, 0x8c, 0x2f, 0xa8, 0x5d, 0x4a,
13522
+	0xb3, 0x77, 0xfb, 0xc5, 0xd1, 0xf5, 0x2e, 0x34, 0xea, 0xaf, 0xb0, 0x55, 0x07, 0xa3, 0x23, 0x7f,
13523
+	0x93, 0x57, 0xb0, 0xdc, 0x6b, 0x9d, 0xd2, 0x9e, 0x5d, 0xca, 0xdc, 0xcb, 0x54, 0x0a, 0xb5, 0x67,
13524
+	0xd3, 0x44, 0x56, 0xfd, 0x84, 0x9b, 0x3e, 0xef, 0x3b, 0xd6, 0x95, 0x8e, 0xfd, 0x90, 0x06, 0x14,
13525
+	0x2e, 0xe8, 0xc5, 0x29, 0xb5, 0xec, 0x5f, 0x1b, 0x03, 0xbb, 0x94, 0xbd, 0x97, 0xa9, 0x14, 0x6b,
13526
+	0x8f, 0xa2, 0xa6, 0xed, 0x78, 0x40, 0xdb, 0xd5, 0x4f, 0x5d, 0xbc, 0xee, 0xb7, 0x25, 0x35, 0x58,
13527
+	0xb2, 0xcc, 0x1e, 0xb5, 0x4b, 0x4b, 0xbc, 0x93, 0xbb, 0x91, 0x73, 0x6f, 0xf6, 0xa8, 0x2e, 0xa0,
13528
+	0xe4, 0x3e, 0xac, 0xb1, 0xa9, 0xf0, 0xe6, 0x60, 0x99, 0xcf, 0xcf, 0x2a, 0x6b, 0x94, 0xa3, 0x2e,
13529
+	0xff, 0x18, 0x0a, 0xbe, 0xd0, 0xc9, 0x06, 0x64, 0xba, 0xf4, 0x4a, 0xd0, 0x42, 0x67, 0x3f, 0xd9,
13530
+	0xec, 0x5e, 0xb6, 0x7a, 0x43, 0x5a, 0x4a, 0xf3, 0x36, 0xf1, 0xf0, 0x41, 0xfa, 0x59, 0x4a, 0x3b,
13531
+	0x80, 0x4d, 0xdf, 0x74, 0x20, 0x47, 0xaa, 0xb0, 0xc4, 0xb2, 0x2f, 0x92, 0x11, 0x47, 0x12, 0x01,
13532
+	0xd3, 0xfe, 0x92, 0x82, 0xcd, 0x93, 0x41, 0xa7, 0xe5, 0xd0, 0x69, 0x19, 0x4a, 0x7e, 0x06, 0xab,
13533
+	0x1c, 0x74, 0x49, 0x2d, 0xdb, 0x30, 0xfb, 0x3c, 0xc0, 0x42, 0xed, 0x8e, 0xca, 0xe3, 0x67, 0x02,
13534
+	0xa2, 0x17, 0x98, 0x01, 0x3e, 0x90, 0x1f, 0x40, 0x96, 0x2d, 0xb7, 0x52, 0x86, 0xdb, 0xdd, 0x8d,
13535
+	0xcb, 0x8b, 0xce, 0x91, 0xda, 0x3e, 0x10, 0x7f, 0xac, 0x33, 0x2d, 0x8b, 0x23, 0xd8, 0xd4, 0xe9,
13536
+	0x85, 0x79, 0x39, 0xfd, 0x78, 0xb7, 0x61, 0xe9, 0xcc, 0xb4, 0xda, 0x22, 0x13, 0x79, 0x5d, 0x3c,
13537
+	0x68, 0xdb, 0x40, 0xfc, 0xfd, 0x89, 0x98, 0x70, 0xd1, 0xbf, 0x6e, 0xd9, 0x5d, 0x9f, 0x0b, 0xa7,
13538
+	0x65, 0x77, 0x43, 0x2e, 0x18, 0x82, 0xb9, 0x60, 0xaf, 0xdc, 0x45, 0x2f, 0xcc, 0xbc, 0xd1, 0xb1,
13539
+	0x97, 0x71, 0xa3, 0xe3, 0x78, 0x8e, 0xd2, 0x9e, 0xc9, 0xd1, 0x4d, 0xed, 0xda, 0x1d, 0x87, 0xdf,
13540
+	0xbb, 0xf6, 0x75, 0x56, 0x88, 0x08, 0x6b, 0x9c, 0x41, 0x44, 0xfc, 0x66, 0xe3, 0x22, 0xf2, 0xaf,
13541
+	0x1b, 0x14, 0x11, 0x55, 0x64, 0x4a, 0x11, 0xd9, 0x83, 0x82, 0x4d, 0xad, 0x4b, 0xa3, 0xcd, 0xd8,
13542
+	0x21, 0x44, 0x04, 0x43, 0x38, 0x16, 0xcd, 0x8d, 0xba, 0xad, 0x03, 0x42, 0x1a, 0x1d, 0x9b, 0x3c,
13543
+	0x84, 0x3c, 0x72, 0x49, 0xa8, 0xc5, 0xca, 0x7e, 0x61, 0x74, 0xbd, 0x9b, 0x13, 0x64, 0xb2, 0xf5,
13544
+	0x9c, 0x60, 0x93, 0x4d, 0xea, 0x50, 0xec, 0x50, 0xdb, 0xb0, 0x68, 0xa7, 0x69, 0x3b, 0x2d, 0x07,
13545
+	0xf5, 0xa1, 0x58, 0xfb, 0x4e, 0x54, 0x8a, 0x8f, 0x19, 0x4a, 0x5f, 0x43, 0x23, 0xfe, 0xa4, 0x10,
13546
+	0x99, 0xdc, 0xb8, 0xc8, 0x90, 0xbb, 0x00, 0xc3, 0x41, 0xd3, 0x31, 0x9b, 0x6c, 0xed, 0x94, 0xf2,
13547
+	0x9c, 0xbe, 0xf9, 0xe1, 0xe0, 0xb5, 0x59, 0x6f, 0x39, 0x94, 0x94, 0x21, 0x6f, 0x0d, 0xfb, 0x8e,
13548
+	0xc1, 0x66, 0x7f, 0x85, 0x5b, 0xbb, 0xcf, 0x0b, 0x90, 0x27, 0x9c, 0x68, 0x4f, 0x9e, 0x18, 0xdf,
13549
+	0x62, 0xe5, 0x89, 0x13, 0x50, 0xc0, 0xb4, 0x43, 0xd8, 0x3e, 0xb0, 0x68, 0xcb, 0xa1, 0x38, 0xd9,
13550
+	0x92, 0x82, 0x4f, 0x51, 0x3b, 0x04, 0xff, 0x76, 0x55, 0xdd, 0xa0, 0x85, 0x4f, 0x3e, 0x8e, 0xe0,
13551
+	0x76, 0xa8, 0x33, 0x8c, 0xea, 0x7d, 0xc8, 0x61, 0x02, 0xb1, 0xc3, 0x3b, 0x31, 0x1d, 0xea, 0x12,
13552
+	0xab, 0xbd, 0x81, 0xcd, 0x17, 0xd4, 0x09, 0x45, 0xf6, 0x04, 0xc0, 0xe3, 0x0b, 0xae, 0xb7, 0xb5,
13553
+	0xd1, 0xf5, 0xee, 0x8a, 0x4b, 0x17, 0x7d, 0xc5, 0x65, 0x0b, 0x79, 0x04, 0xeb, 0x46, 0xdf, 0xa6,
13554
+	0x96, 0xd3, 0xec, 0xd0, 0xb3, 0xd6, 0xb0, 0xe7, 0xd8, 0xa8, 0x2e, 0x45, 0xd1, 0x5c, 0xc7, 0x56,
13555
+	0xed, 0x10, 0x88, 0xdf, 0xd7, 0x7c, 0x81, 0xff, 0x2d, 0x0d, 0xdb, 0x42, 0x48, 0xe7, 0x0a, 0xbe,
13556
+	0x0e, 0xeb, 0x12, 0x3d, 0xc5, 0x37, 0xa0, 0x88, 0x36, 0xf2, 0x33, 0xf0, 0x34, 0xf0, 0x19, 0x98,
13557
+	0x2c, 0x95, 0xe4, 0x53, 0xc8, 0x5b, 0x66, 0xaf, 0x77, 0xda, 0x6a, 0x77, 0x4b, 0xd9, 0x7b, 0xa9,
13558
+	0x4a, 0xb1, 0xf6, 0x9e, 0xca, 0x50, 0x35, 0xc8, 0xaa, 0x8e, 0x86, 0xba, 0xdb, 0x85, 0xa6, 0x41,
13559
+	0x5e, 0xb6, 0x92, 0x3c, 0x64, 0x8f, 0x5e, 0x1e, 0x3d, 0xdf, 0xb8, 0x45, 0x56, 0x21, 0xff, 0x4a,
13560
+	0x7f, 0xfe, 0x59, 0xe3, 0xe5, 0xc9, 0xf1, 0x46, 0x8a, 0xb1, 0x27, 0xd4, 0xdd, 0x7c, 0x49, 0xa8,
13561
+	0xc3, 0xb6, 0x10, 0xdc, 0x79, 0x72, 0xa0, 0x7d, 0x1b, 0x6e, 0x87, 0x7a, 0x41, 0xe5, 0xfe, 0x2a,
13562
+	0x03, 0x5b, 0x6c, 0xfd, 0x61, 0xbb, 0x2b, 0xde, 0x8d, 0xb0, 0x78, 0xef, 0x45, 0x49, 0x64, 0xc8,
13563
+	0x72, 0x5c, 0xbf, 0xff, 0x9c, 0x5e, 0xb8, 0x7e, 0x1f, 0x87, 0xf4, 0xfb, 0x27, 0x53, 0x06, 0xa7,
13564
+	0x94, 0xf0, 0x31, 0x8d, 0xcc, 0x2a, 0x34, 0xd2, 0xaf, 0x82, 0x4b, 0x8b, 0x53, 0xc1, 0x97, 0xb0,
13565
+	0x1d, 0x0c, 0x17, 0x49, 0xf3, 0x23, 0xc8, 0x63, 0x12, 0xa5, 0x16, 0xc6, 0xb2, 0xc6, 0x05, 0x7b,
13566
+	0x8a, 0x78, 0x44, 0x9d, 0xcf, 0x4d, 0xab, 0x3b, 0x85, 0x22, 0xa2, 0x85, 0x4a, 0x11, 0xdd, 0xce,
13567
+	0x3c, 0x4e, 0xf7, 0x45, 0x53, 0x1c, 0xa7, 0xa5, 0x95, 0xc4, 0x6a, 0x27, 0x5c, 0x11, 0x43, 0x91,
13568
+	0x11, 0xc8, 0xb2, 0x99, 0xc6, 0xf9, 0xe2, 0xbf, 0x19, 0xc9, 0xd1, 0x86, 0x91, 0x3c, 0xed, 0x91,
13569
+	0x1c, 0x6d, 0x19, 0xc9, 0x11, 0xd0, 0xe8, 0xa0, 0xf8, 0x2d, 0x28, 0xc6, 0x5f, 0xc9, 0x75, 0xb7,
13570
+	0xf0, 0x30, 0xdd, 0xb5, 0x18, 0x8a, 0x54, 0xfb, 0x6f, 0x5a, 0xac, 0x45, 0x6c, 0x9f, 0x61, 0x2d,
13571
+	0x86, 0x2c, 0xc7, 0xd7, 0xe2, 0x1f, 0x6e, 0x70, 0x2d, 0x46, 0x04, 0x37, 0xf3, 0x5a, 0x5c, 0xc0,
13572
+	0x7a, 0xf3, 0x42, 0xf2, 0xd6, 0x1b, 0x26, 0x2a, 0x76, 0xbd, 0xc9, 0xcc, 0xb9, 0x60, 0xed, 0x43,
13573
+	0x4e, 0xe9, 0x83, 0xde, 0xd0, 0x76, 0xa8, 0xe5, 0xd3, 0xe8, 0xb6, 0x68, 0x09, 0x69, 0x34, 0xe2,
13574
+	0x18, 0x2f, 0x10, 0xe0, 0xd2, 0xd7, 0xed, 0xc2, 0xa3, 0x2f, 0x42, 0xe2, 0xe8, 0x2b, 0xad, 0x24,
13575
+	0xd6, 0xe5, 0x12, 0xbe, 0x98, 0x81, 0x4b, 0x21, 0xcb, 0x77, 0x8b, 0x4b, 0x11, 0xc1, 0xdd, 0x24,
13576
+	0x97, 0xbc, 0x90, 0x3c, 0x2e, 0x61, 0x36, 0x62, 0xb9, 0x24, 0x53, 0xe7, 0x82, 0xb5, 0x3f, 0xa6,
13577
+	0xa0, 0x70, 0x48, 0xaf, 0x74, 0xd3, 0x69, 0x39, 0x6c, 0xeb, 0xf3, 0x3d, 0xd8, 0x64, 0x24, 0xa3,
13578
+	0x56, 0xf3, 0x8d, 0x69, 0xf4, 0x9b, 0x8e, 0xd9, 0xa5, 0x7d, 0x1e, 0x5a, 0x5e, 0x5f, 0x17, 0x2f,
13579
+	0x3e, 0x36, 0x8d, 0xfe, 0x6b, 0xd6, 0x4c, 0x9e, 0x00, 0xb9, 0x68, 0xf5, 0x5b, 0xe7, 0x41, 0xb0,
13580
+	0xd8, 0x2c, 0x6e, 0xe0, 0x1b, 0x25, 0x7a, 0xd8, 0xef, 0x99, 0xed, 0x6e, 0x93, 0x8d, 0x3a, 0x13,
13581
+	0x40, 0x9f, 0xf0, 0x17, 0x87, 0xf4, 0x4a, 0xfb, 0xbd, 0xbb, 0x1f, 0x9c, 0x87, 0xe7, 0x6c, 0x3f,
13582
+	0x28, 0xd1, 0xd3, 0xec, 0x07, 0xd1, 0x66, 0x8a, 0xfd, 0x20, 0x7a, 0xf7, 0xed, 0x07, 0x3f, 0x64,
13583
+	0xfb, 0x41, 0x31, 0xab, 0x7c, 0x3f, 0x18, 0x61, 0xe8, 0x9b, 0xfc, 0xfd, 0xec, 0xdb, 0xeb, 0xdd,
13584
+	0x5b, 0xba, 0x6b, 0xe6, 0xed, 0xef, 0x16, 0xb4, 0x50, 0x7f, 0x0a, 0x1b, 0x7c, 0xc7, 0xde, 0xb6,
13585
+	0xa8, 0x23, 0xe7, 0xf3, 0x31, 0xac, 0xd8, 0xbc, 0xc1, 0x9b, 0xce, 0xd5, 0xd1, 0xf5, 0x6e, 0x5e,
13586
+	0xa0, 0x1a, 0x75, 0xf6, 0x9d, 0xe7, 0xbf, 0x3a, 0xda, 0x0b, 0x3c, 0x5c, 0x08, 0x73, 0x0c, 0xa5,
13587
+	0x06, 0xcb, 0x02, 0x80, 0x91, 0x94, 0xd5, 0x7b, 0x06, 0x6e, 0x83, 0x48, 0xed, 0xeb, 0x14, 0x6c,
13588
+	0xc9, 0x8d, 0xeb, 0x6c, 0xb1, 0x90, 0x7d, 0x28, 0x22, 0x74, 0x8a, 0xbc, 0xae, 0x09, 0x13, 0x99,
13589
+	0xd6, 0x5a, 0x20, 0xad, 0x3b, 0xd1, 0x81, 0xfb, 0xb6, 0x27, 0x1f, 0x7b, 0xc7, 0x94, 0xb9, 0xa7,
13590
+	0xe1, 0x3f, 0x69, 0x20, 0x62, 0x27, 0xc6, 0x1e, 0x5d, 0xd9, 0xfc, 0x65, 0x58, 0x36, 0xab, 0xd1,
13591
+	0x3b, 0x4e, 0xbf, 0xe1, 0xb8, 0x6a, 0x7e, 0xb5, 0x78, 0xd5, 0xd4, 0x43, 0xaa, 0xf9, 0xc1, 0x74,
13592
+	0xb1, 0xdd, 0x88, 0x68, 0x1e, 0xca, 0x63, 0x07, 0x46, 0x84, 0x29, 0xfb, 0x21, 0x3b, 0x24, 0xf1,
13593
+	0x26, 0x94, 0xcc, 0xb8, 0x9c, 0x49, 0xa8, 0xd6, 0x80, 0x2d, 0x79, 0x62, 0xf7, 0x53, 0xb7, 0x16,
13594
+	0xd8, 0xeb, 0x4e, 0xcc, 0xa5, 0x60, 0x57, 0x73, 0x70, 0xe9, 0x17, 0xb0, 0x25, 0x0f, 0x5d, 0x33,
13595
+	0xae, 0xee, 0x6f, 0x79, 0x87, 0x3f, 0x7f, 0x34, 0x28, 0x1a, 0x07, 0x66, 0xff, 0xcc, 0x38, 0xf7,
13596
+	0x75, 0xdb, 0xe6, 0x0d, 0xa1, 0x6e, 0x05, 0x8a, 0x75, 0x2b, 0x5e, 0xbb, 0xa2, 0x21, 0xcd, 0xbd,
13597
+	0x11, 0x0a, 0x40, 0xdc, 0x08, 0xd1, 0x06, 0x91, 0x3e, 0xd1, 0x98, 0x35, 0x16, 0x26, 0x1a, 0x08,
13598
+	0x9d, 0x46, 0x34, 0x84, 0xc9, 0x14, 0xa2, 0x21, 0x3c, 0xab, 0x44, 0x63, 0x01, 0xd3, 0x20, 0x45,
13599
+	0x43, 0x34, 0xcf, 0x20, 0x1a, 0x41, 0xc3, 0x77, 0x4b, 0x34, 0xd4, 0xb1, 0xdd, 0xa4, 0x68, 0xb8,
13600
+	0x11, 0x79, 0xa2, 0x21, 0x12, 0x11, 0x2b, 0x1a, 0x98, 0x33, 0x09, 0xf5, 0x44, 0x23, 0x48, 0xdd,
13601
+	0x09, 0x44, 0x43, 0xc5, 0xa5, 0x60, 0x57, 0x73, 0x70, 0xc9, 0x15, 0x8d, 0x99, 0x57, 0xb7, 0x2b,
13602
+	0x1a, 0xc1, 0x68, 0x6a, 0x5f, 0xde, 0x81, 0xdc, 0x81, 0xb8, 0xdb, 0x24, 0x06, 0xe4, 0xf0, 0xda,
13603
+	0x90, 0x68, 0xaa, 0xa0, 0x82, 0x57, 0x91, 0xe5, 0xfb, 0xb1, 0x18, 0x14, 0xa5, 0xdb, 0x7f, 0xff,
13604
+	0xeb, 0xff, 0xfe, 0x94, 0x5e, 0x87, 0x35, 0x0e, 0xfa, 0x3e, 0x6e, 0x1f, 0x89, 0x09, 0x2b, 0xee,
13605
+	0xfd, 0x13, 0xf9, 0xee, 0x24, 0xb7, 0x75, 0xe5, 0x07, 0x09, 0xa8, 0x78, 0x87, 0x16, 0x80, 0x77,
13606
+	0xfd, 0x43, 0x1e, 0x44, 0x17, 0xfc, 0xfc, 0x23, 0x7c, 0x98, 0x04, 0x4b, 0xf4, 0xe9, 0x5d, 0xef,
13607
+	0xa8, 0x7d, 0x8e, 0x5d, 0x27, 0xa9, 0x7d, 0x2a, 0x6e, 0x89, 0x22, 0x7c, 0x8a, 0x1c, 0xbe, 0x6e,
13608
+	0xd9, 0xdd, 0xc8, 0x1c, 0xfa, 0xae, 0x77, 0x22, 0x73, 0x18, 0xb8, 0xc8, 0x89, 0xcf, 0x21, 0x2f,
13609
+	0xd2, 0x47, 0xe7, 0xd0, 0x7f, 0x59, 0x12, 0x9d, 0xc3, 0x40, 0xa5, 0x3f, 0x71, 0x3e, 0xf9, 0xf0,
13610
+	0x62, 0xe6, 0xd3, 0x3f, 0xc2, 0x87, 0x49, 0xb0, 0x44, 0x9f, 0x5e, 0xed, 0x5c, 0xed, 0x73, 0xac,
13611
+	0x8e, 0xaf, 0xf6, 0x39, 0x5e, 0x82, 0x8f, 0xf2, 0xf9, 0x05, 0xac, 0xfa, 0xeb, 0x7e, 0xe4, 0xd1,
13612
+	0x84, 0x85, 0xcc, 0x72, 0x25, 0x19, 0x18, 0xef, 0xf9, 0xb7, 0xb0, 0x16, 0xb8, 0xe5, 0x20, 0xca,
13613
+	0x1e, 0x55, 0xb7, 0x2a, 0xe5, 0xc7, 0x13, 0x20, 0x13, 0x9d, 0x07, 0x8a, 0xe4, 0x6a, 0xe7, 0xaa,
13614
+	0xb2, 0xbc, 0xda, 0xb9, 0xb2, 0xe2, 0x1e, 0xe3, 0x3c, 0x50, 0x0b, 0x57, 0x3b, 0x57, 0x15, 0xdd,
13615
+	0xd5, 0xce, 0xd5, 0x85, 0xf5, 0x58, 0x92, 0x61, 0xfd, 0x28, 0x92, 0x64, 0xc1, 0x9a, 0x63, 0x24,
13616
+	0xc9, 0xc2, 0x05, 0xc4, 0x78, 0x92, 0xc9, 0x62, 0x57, 0x34, 0xc9, 0x42, 0x15, 0xba, 0x68, 0x92,
13617
+	0x85, 0xeb, 0x66, 0x89, 0x24, 0x93, 0x03, 0x8e, 0x21, 0x59, 0x68, 0xcc, 0x8f, 0x27, 0x40, 0x4e,
13618
+	0x98, 0xe7, 0x58, 0xe7, 0xaa, 0x22, 0x6f, 0x5c, 0x9e, 0x27, 0x74, 0x2e, 0xf2, 0x8c, 0xa7, 0xfd,
13619
+	0xc8, 0x3c, 0x07, 0xeb, 0x28, 0x91, 0x79, 0x0e, 0x95, 0x1a, 0x12, 0xf2, 0x2c, 0x0b, 0x51, 0xd1,
13620
+	0x79, 0x0e, 0x55, 0xcf, 0xa2, 0xf3, 0x1c, 0xae, 0x69, 0x25, 0xae, 0x67, 0x39, 0xe0, 0x98, 0xf5,
13621
+	0x1c, 0x1a, 0xf3, 0xe3, 0x09, 0x90, 0x89, 0x1f, 0x27, 0xb7, 0x04, 0xa2, 0xfe, 0x38, 0x85, 0x0b,
13622
+	0x2c, 0xe5, 0x07, 0x09, 0xa8, 0xc4, 0x79, 0xf6, 0xd7, 0x1b, 0xd4, 0xf3, 0xac, 0xa8, 0xa5, 0x94,
13623
+	0x2b, 0xc9, 0xc0, 0x78, 0xcf, 0x43, 0x28, 0xf8, 0x4e, 0xcd, 0xe4, 0xe1, 0x64, 0x07, 0xfd, 0xf2,
13624
+	0xa3, 0x44, 0x5c, 0xe2, 0x80, 0xfd, 0x87, 0x62, 0xf5, 0x80, 0x15, 0x27, 0xf0, 0x72, 0x25, 0x19,
13625
+	0x98, 0xe8, 0xd9, 0x7f, 0x00, 0x56, 0x7b, 0x56, 0x1c, 0xb2, 0xcb, 0x95, 0x64, 0xe0, 0x24, 0xac,
13626
+	0x12, 0x5b, 0xe8, 0x48, 0x56, 0x05, 0xf6, 0xe8, 0x91, 0xac, 0x0a, 0xee, 0xc3, 0x13, 0x59, 0x85,
13627
+	0x3e, 0x63, 0x58, 0x15, 0x74, 0x5b, 0x49, 0x06, 0x4e, 0xc4, 0x2a, 0x3c, 0x56, 0x45, 0xb3, 0x2a,
13628
+	0x78, 0x12, 0x8c, 0x66, 0x55, 0xe8, 0x7c, 0x96, 0xc8, 0xaa, 0xb8, 0x01, 0x2b, 0x8e, 0x68, 0x71,
13629
+	0xac, 0x9a, 0x78, 0xaa, 0xfd, 0x27, 0xa4, 0x38, 0x56, 0x4d, 0xe0, 0x59, 0x75, 0xd8, 0x8a, 0xf0,
13630
+	0xbc, 0x5f, 0x7a, 0xfb, 0xcd, 0xce, 0xad, 0x7f, 0x7e, 0xb3, 0x73, 0xeb, 0x77, 0xa3, 0x9d, 0xd4,
13631
+	0xdb, 0xd1, 0x4e, 0xea, 0x1f, 0xa3, 0x9d, 0xd4, 0xbf, 0x47, 0x3b, 0xa9, 0xd3, 0x65, 0xfe, 0x6f,
13632
+	0xa0, 0x4f, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x16, 0x80, 0xb3, 0xa3, 0x7f, 0x2a, 0x00, 0x00,
13622 13633
 }
... ...
@@ -92,7 +92,7 @@ service Control {
92 92
 		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
93 93
 	};
94 94
 
95
-	// ListSecrets returns a `ListSecretResponse` with a list all non-internal `Secret`s being
95
+	// ListSecrets returns a `ListSecretResponse` with a list of all non-internal `Secret`s being
96 96
 	// managed, or all secrets matching any name in `ListSecretsRequest.Names`, any
97 97
 	// name prefix in `ListSecretsRequest.NamePrefixes`, any id in
98 98
 	// `ListSecretsRequest.SecretIDs`, or any id prefix in `ListSecretsRequest.IDPrefixes`.
... ...
@@ -116,6 +116,51 @@ service Control {
116 116
 	rpc RemoveSecret(RemoveSecretRequest) returns (RemoveSecretResponse) {
117 117
 		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
118 118
 	}
119
+
120
+	// --- config APIs ---
121
+
122
+	// GetConfig returns a `GetConfigResponse` with a `Config` with the same
123
+	// id as `GetConfigRequest.ConfigID`
124
+	// - Returns `NotFound` if the Config with the given id is not found.
125
+	// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
126
+	// - Returns an error if getting fails.
127
+	rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {
128
+		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
129
+	}
130
+
131
+	// UpdateConfig returns a `UpdateConfigResponse` with a `Config` with the same
132
+	// id as `GetConfigRequest.ConfigID`
133
+	// - Returns `NotFound` if the Config with the given id is not found.
134
+	// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
135
+	// - Returns an error if updating fails.
136
+	rpc UpdateConfig(UpdateConfigRequest) returns (UpdateConfigResponse) {
137
+		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
138
+	};
139
+
140
+	// ListConfigs returns a `ListConfigResponse` with a list of `Config`s being
141
+	// managed, or all configs matching any name in `ListConfigsRequest.Names`, any
142
+	// name prefix in `ListConfigsRequest.NamePrefixes`, any id in
143
+	// `ListConfigsRequest.ConfigIDs`, or any id prefix in `ListConfigsRequest.IDPrefixes`.
144
+	// - Returns an error if listing fails.
145
+	rpc ListConfigs(ListConfigsRequest) returns (ListConfigsResponse) {
146
+		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
147
+	}
148
+	// CreateConfig creates and return a `CreateConfigResponse` with a `Config` based
149
+	// on the provided `CreateConfigRequest.ConfigSpec`.
150
+	// - Returns `InvalidArgument` if the `CreateConfigRequest.ConfigSpec` is malformed,
151
+	//   or if the config data is too long or contains invalid characters.
152
+	// - Returns an error if the creation fails.
153
+	rpc CreateConfig(CreateConfigRequest) returns (CreateConfigResponse) {
154
+		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
155
+	}
156
+
157
+	// RemoveConfig removes the config referenced by `RemoveConfigRequest.ID`.
158
+	// - Returns `InvalidArgument` if `RemoveConfigRequest.ID` is empty.
159
+	// - Returns `NotFound` if the a config named `RemoveConfigRequest.ID` is not found.
160
+	// - Returns an error if the deletion fails.
161
+	rpc RemoveConfig(RemoveConfigRequest) returns (RemoveConfigResponse) {
162
+		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
163
+	}
119 164
 }
120 165
 
121 166
 message GetNodeRequest {
... ...
@@ -396,7 +441,6 @@ message UpdateSecretResponse {
396 396
 	Secret secret = 1;
397 397
 }
398 398
 
399
-
400 399
 // ListSecretRequest is the request to list all non-internal secrets in the secret store,
401 400
 // or all secrets filtered by (name or name prefix or id prefix) and labels.
402 401
 message ListSecretsRequest {
... ...
@@ -424,7 +468,7 @@ message CreateSecretRequest {
424 424
 	SecretSpec spec = 1;
425 425
 }
426 426
 
427
-// CreateSecretResponse contains the newly created `Secret`` corresponding to the
427
+// CreateSecretResponse contains the newly created `Secret` corresponding to the
428 428
 // name in `CreateSecretRequest`.  The `Secret.Spec.Data` field should be nil instead
429 429
 // of actually containing the secret bytes.
430 430
 message CreateSecretResponse {
... ...
@@ -440,3 +484,71 @@ message RemoveSecretRequest {
440 440
 // RemoveSecretResponse is an empty object indicating the successful removal of
441 441
 // a secret.
442 442
 message RemoveSecretResponse {}
443
+
444
+// GetConfigRequest is the request to get a `Config` object given a config id.
445
+message GetConfigRequest {
446
+	string config_id = 1;
447
+}
448
+
449
+// GetConfigResponse contains the Config corresponding to the id in
450
+// `GetConfigRequest`.
451
+message GetConfigResponse {
452
+	Config config = 1;
453
+}
454
+
455
+message UpdateConfigRequest {
456
+	// ConfigID is the config ID to update.
457
+	string config_id = 1;
458
+
459
+	// ConfigVersion is the version of the config being updated.
460
+	Version config_version = 2;
461
+
462
+	// Spec is the new spec to apply to the Config
463
+	// Only some fields are allowed to be updated.
464
+	ConfigSpec spec = 3;
465
+}
466
+
467
+message UpdateConfigResponse {
468
+	Config config = 1;
469
+}
470
+
471
+// ListConfigRequest is the request to list all configs in the config store,
472
+// or all configs filtered by (name or name prefix or id prefix) and labels.
473
+message ListConfigsRequest {
474
+	message Filters {
475
+		repeated string names = 1;
476
+		repeated string id_prefixes = 2;
477
+		map<string, string> labels = 3;
478
+		repeated string name_prefixes = 4;
479
+	}
480
+
481
+	Filters filters = 1;
482
+}
483
+
484
+// ListConfigResponse contains a list of all the configs that match the name or
485
+// name prefix filters provided in `ListConfigRequest`.
486
+message ListConfigsResponse {
487
+	repeated Config configs = 1;
488
+}
489
+
490
+// CreateConfigRequest specifies a new config (it will not update an existing
491
+// config) to create.
492
+message CreateConfigRequest {
493
+	ConfigSpec spec = 1;
494
+}
495
+
496
+// CreateConfigResponse contains the newly created `Config` corresponding to the
497
+// name in `CreateConfigRequest`.
498
+message CreateConfigResponse {
499
+	Config config = 1;
500
+}
501
+
502
+// RemoveConfigRequest contains the ID of the config that should be removed.  This
503
+// removes all versions of the config.
504
+message RemoveConfigRequest {
505
+	string config_id = 1;
506
+}
507
+
508
+// RemoveConfigResponse is an empty object indicating the successful removal of
509
+// a config.
510
+message RemoveConfigResponse {}
... ...
@@ -21,7 +21,8 @@ var Service = api.ServiceSpec{
21 21
 		},
22 22
 		Resources: &api.ResourceRequirements{},
23 23
 		Restart: &api.RestartPolicy{
24
-			Delay: gogotypes.DurationProto(5 * time.Second),
24
+			Condition: api.RestartOnAny,
25
+			Delay:     gogotypes.DurationProto(5 * time.Second),
25 26
 		},
26 27
 		Placement: &api.Placement{},
27 28
 	},
... ...
@@ -31,6 +32,12 @@ var Service = api.ServiceSpec{
31 31
 		Parallelism:   1,
32 32
 		Order:         api.UpdateConfig_STOP_FIRST,
33 33
 	},
34
+	Rollback: &api.UpdateConfig{
35
+		FailureAction: api.UpdateConfig_PAUSE,
36
+		Monitor:       gogotypes.DurationProto(5 * time.Second),
37
+		Parallelism:   1,
38
+		Order:         api.UpdateConfig_STOP_FIRST,
39
+	},
34 40
 }
35 41
 
36 42
 // InterpolateService returns a ServiceSpec based on the provided spec, which
... ...
@@ -79,5 +86,14 @@ func InterpolateService(origSpec *api.ServiceSpec) *api.ServiceSpec {
79 79
 		}
80 80
 	}
81 81
 
82
+	if spec.Rollback == nil {
83
+		spec.Rollback = Service.Rollback.Copy()
84
+	} else {
85
+		if spec.Rollback.Monitor == nil {
86
+			spec.Rollback.Monitor = &gogotypes.Duration{}
87
+			deepcopy.Copy(spec.Rollback.Monitor, Service.Rollback.Monitor)
88
+		}
89
+	}
90
+
82 91
 	return spec
83 92
 }
... ...
@@ -154,6 +154,8 @@ type SessionMessage struct {
154 154
 	// Symmetric encryption key distributed by the lead manager. Used by agents
155 155
 	// for securing network bootstrapping and communication.
156 156
 	NetworkBootstrapKeys []*EncryptionKey `protobuf:"bytes,4,rep,name=network_bootstrap_keys,json=networkBootstrapKeys" json:"network_bootstrap_keys,omitempty"`
157
+	// Which root certificates to trust
158
+	RootCA []byte `protobuf:"bytes,5,opt,name=RootCA,proto3" json:"RootCA,omitempty"`
157 159
 }
158 160
 
159 161
 func (m *SessionMessage) Reset()                    { *m = SessionMessage{} }
... ...
@@ -244,6 +246,7 @@ type Assignment struct {
244 244
 	// Types that are valid to be assigned to Item:
245 245
 	//	*Assignment_Task
246 246
 	//	*Assignment_Secret
247
+	//	*Assignment_Config
247 248
 	Item isAssignment_Item `protobuf_oneof:"item"`
248 249
 }
249 250
 
... ...
@@ -263,9 +266,13 @@ type Assignment_Task struct {
263 263
 type Assignment_Secret struct {
264 264
 	Secret *Secret `protobuf:"bytes,2,opt,name=secret,oneof"`
265 265
 }
266
+type Assignment_Config struct {
267
+	Config *Config `protobuf:"bytes,3,opt,name=config,oneof"`
268
+}
266 269
 
267 270
 func (*Assignment_Task) isAssignment_Item()   {}
268 271
 func (*Assignment_Secret) isAssignment_Item() {}
272
+func (*Assignment_Config) isAssignment_Item() {}
269 273
 
270 274
 func (m *Assignment) GetItem() isAssignment_Item {
271 275
 	if m != nil {
... ...
@@ -288,11 +295,19 @@ func (m *Assignment) GetSecret() *Secret {
288 288
 	return nil
289 289
 }
290 290
 
291
+func (m *Assignment) GetConfig() *Config {
292
+	if x, ok := m.GetItem().(*Assignment_Config); ok {
293
+		return x.Config
294
+	}
295
+	return nil
296
+}
297
+
291 298
 // XXX_OneofFuncs is for the internal use of the proto package.
292 299
 func (*Assignment) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
293 300
 	return _Assignment_OneofMarshaler, _Assignment_OneofUnmarshaler, _Assignment_OneofSizer, []interface{}{
294 301
 		(*Assignment_Task)(nil),
295 302
 		(*Assignment_Secret)(nil),
303
+		(*Assignment_Config)(nil),
296 304
 	}
297 305
 }
298 306
 
... ...
@@ -310,6 +325,11 @@ func _Assignment_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
310 310
 		if err := b.EncodeMessage(x.Secret); err != nil {
311 311
 			return err
312 312
 		}
313
+	case *Assignment_Config:
314
+		_ = b.EncodeVarint(3<<3 | proto.WireBytes)
315
+		if err := b.EncodeMessage(x.Config); err != nil {
316
+			return err
317
+		}
313 318
 	case nil:
314 319
 	default:
315 320
 		return fmt.Errorf("Assignment.Item has unexpected type %T", x)
... ...
@@ -336,6 +356,14 @@ func _Assignment_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buf
336 336
 		err := b.DecodeMessage(msg)
337 337
 		m.Item = &Assignment_Secret{msg}
338 338
 		return true, err
339
+	case 3: // item.config
340
+		if wire != proto.WireBytes {
341
+			return true, proto.ErrInternalBadWireType
342
+		}
343
+		msg := new(Config)
344
+		err := b.DecodeMessage(msg)
345
+		m.Item = &Assignment_Config{msg}
346
+		return true, err
339 347
 	default:
340 348
 		return false, nil
341 349
 	}
... ...
@@ -355,6 +383,11 @@ func _Assignment_OneofSizer(msg proto.Message) (n int) {
355 355
 		n += proto.SizeVarint(2<<3 | proto.WireBytes)
356 356
 		n += proto.SizeVarint(uint64(s))
357 357
 		n += s
358
+	case *Assignment_Config:
359
+		s := proto.Size(x.Config)
360
+		n += proto.SizeVarint(3<<3 | proto.WireBytes)
361
+		n += proto.SizeVarint(uint64(s))
362
+		n += s
358 363
 	case nil:
359 364
 	default:
360 365
 		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
... ...
@@ -513,6 +546,10 @@ func (m *SessionMessage) CopyFrom(src interface{}) {
513 513
 		}
514 514
 	}
515 515
 
516
+	if o.RootCA != nil {
517
+		m.RootCA = make([]byte, len(o.RootCA))
518
+		copy(m.RootCA, o.RootCA)
519
+	}
516 520
 }
517 521
 
518 522
 func (m *HeartbeatRequest) Copy() *HeartbeatRequest {
... ...
@@ -678,6 +715,12 @@ func (m *Assignment) CopyFrom(src interface{}) {
678 678
 			}
679 679
 			github_com_docker_swarmkit_api_deepcopy.Copy(v.Secret, o.GetSecret())
680 680
 			m.Item = &v
681
+		case *Assignment_Config:
682
+			v := Assignment_Config{
683
+				Config: &Config{},
684
+			}
685
+			github_com_docker_swarmkit_api_deepcopy.Copy(v.Config, o.GetConfig())
686
+			m.Item = &v
681 687
 		}
682 688
 	}
683 689
 
... ...
@@ -1148,6 +1191,12 @@ func (m *SessionMessage) MarshalTo(dAtA []byte) (int, error) {
1148 1148
 			i += n
1149 1149
 		}
1150 1150
 	}
1151
+	if len(m.RootCA) > 0 {
1152
+		dAtA[i] = 0x2a
1153
+		i++
1154
+		i = encodeVarintDispatcher(dAtA, i, uint64(len(m.RootCA)))
1155
+		i += copy(dAtA[i:], m.RootCA)
1156
+	}
1151 1157
 	return i, nil
1152 1158
 }
1153 1159
 
... ...
@@ -1420,6 +1469,20 @@ func (m *Assignment_Secret) MarshalTo(dAtA []byte) (int, error) {
1420 1420
 	}
1421 1421
 	return i, nil
1422 1422
 }
1423
+func (m *Assignment_Config) MarshalTo(dAtA []byte) (int, error) {
1424
+	i := 0
1425
+	if m.Config != nil {
1426
+		dAtA[i] = 0x1a
1427
+		i++
1428
+		i = encodeVarintDispatcher(dAtA, i, uint64(m.Config.Size()))
1429
+		n8, err := m.Config.MarshalTo(dAtA[i:])
1430
+		if err != nil {
1431
+			return 0, err
1432
+		}
1433
+		i += n8
1434
+	}
1435
+	return i, nil
1436
+}
1423 1437
 func (m *AssignmentChange) Marshal() (dAtA []byte, err error) {
1424 1438
 	size := m.Size()
1425 1439
 	dAtA = make([]byte, size)
... ...
@@ -1439,11 +1502,11 @@ func (m *AssignmentChange) MarshalTo(dAtA []byte) (int, error) {
1439 1439
 		dAtA[i] = 0xa
1440 1440
 		i++
1441 1441
 		i = encodeVarintDispatcher(dAtA, i, uint64(m.Assignment.Size()))
1442
-		n8, err := m.Assignment.MarshalTo(dAtA[i:])
1442
+		n9, err := m.Assignment.MarshalTo(dAtA[i:])
1443 1443
 		if err != nil {
1444 1444
 			return 0, err
1445 1445
 		}
1446
-		i += n8
1446
+		i += n9
1447 1447
 	}
1448 1448
 	if m.Action != 0 {
1449 1449
 		dAtA[i] = 0x10
... ...
@@ -1860,6 +1923,10 @@ func (m *SessionMessage) Size() (n int) {
1860 1860
 			n += 1 + l + sovDispatcher(uint64(l))
1861 1861
 		}
1862 1862
 	}
1863
+	l = len(m.RootCA)
1864
+	if l > 0 {
1865
+		n += 1 + l + sovDispatcher(uint64(l))
1866
+	}
1863 1867
 	return n
1864 1868
 }
1865 1869
 
... ...
@@ -1976,6 +2043,15 @@ func (m *Assignment_Secret) Size() (n int) {
1976 1976
 	}
1977 1977
 	return n
1978 1978
 }
1979
+func (m *Assignment_Config) Size() (n int) {
1980
+	var l int
1981
+	_ = l
1982
+	if m.Config != nil {
1983
+		l = m.Config.Size()
1984
+		n += 1 + l + sovDispatcher(uint64(l))
1985
+	}
1986
+	return n
1987
+}
1979 1988
 func (m *AssignmentChange) Size() (n int) {
1980 1989
 	var l int
1981 1990
 	_ = l
... ...
@@ -2045,6 +2121,7 @@ func (this *SessionMessage) String() string {
2045 2045
 		`Node:` + strings.Replace(fmt.Sprintf("%v", this.Node), "Node", "Node", 1) + `,`,
2046 2046
 		`Managers:` + strings.Replace(fmt.Sprintf("%v", this.Managers), "WeightedPeer", "WeightedPeer", 1) + `,`,
2047 2047
 		`NetworkBootstrapKeys:` + strings.Replace(fmt.Sprintf("%v", this.NetworkBootstrapKeys), "EncryptionKey", "EncryptionKey", 1) + `,`,
2048
+		`RootCA:` + fmt.Sprintf("%v", this.RootCA) + `,`,
2048 2049
 		`}`,
2049 2050
 	}, "")
2050 2051
 	return s
... ...
@@ -2160,6 +2237,16 @@ func (this *Assignment_Secret) String() string {
2160 2160
 	}, "")
2161 2161
 	return s
2162 2162
 }
2163
+func (this *Assignment_Config) String() string {
2164
+	if this == nil {
2165
+		return "nil"
2166
+	}
2167
+	s := strings.Join([]string{`&Assignment_Config{`,
2168
+		`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
2169
+		`}`,
2170
+	}, "")
2171
+	return s
2172
+}
2163 2173
 func (this *AssignmentChange) String() string {
2164 2174
 	if this == nil {
2165 2175
 		return "nil"
... ...
@@ -2457,6 +2544,37 @@ func (m *SessionMessage) Unmarshal(dAtA []byte) error {
2457 2457
 				return err
2458 2458
 			}
2459 2459
 			iNdEx = postIndex
2460
+		case 5:
2461
+			if wireType != 2 {
2462
+				return fmt.Errorf("proto: wrong wireType = %d for field RootCA", wireType)
2463
+			}
2464
+			var byteLen int
2465
+			for shift := uint(0); ; shift += 7 {
2466
+				if shift >= 64 {
2467
+					return ErrIntOverflowDispatcher
2468
+				}
2469
+				if iNdEx >= l {
2470
+					return io.ErrUnexpectedEOF
2471
+				}
2472
+				b := dAtA[iNdEx]
2473
+				iNdEx++
2474
+				byteLen |= (int(b) & 0x7F) << shift
2475
+				if b < 0x80 {
2476
+					break
2477
+				}
2478
+			}
2479
+			if byteLen < 0 {
2480
+				return ErrInvalidLengthDispatcher
2481
+			}
2482
+			postIndex := iNdEx + byteLen
2483
+			if postIndex > l {
2484
+				return io.ErrUnexpectedEOF
2485
+			}
2486
+			m.RootCA = append(m.RootCA[:0], dAtA[iNdEx:postIndex]...)
2487
+			if m.RootCA == nil {
2488
+				m.RootCA = []byte{}
2489
+			}
2490
+			iNdEx = postIndex
2460 2491
 		default:
2461 2492
 			iNdEx = preIndex
2462 2493
 			skippy, err := skipDispatcher(dAtA[iNdEx:])
... ...
@@ -3241,6 +3359,38 @@ func (m *Assignment) Unmarshal(dAtA []byte) error {
3241 3241
 			}
3242 3242
 			m.Item = &Assignment_Secret{v}
3243 3243
 			iNdEx = postIndex
3244
+		case 3:
3245
+			if wireType != 2 {
3246
+				return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
3247
+			}
3248
+			var msglen int
3249
+			for shift := uint(0); ; shift += 7 {
3250
+				if shift >= 64 {
3251
+					return ErrIntOverflowDispatcher
3252
+				}
3253
+				if iNdEx >= l {
3254
+					return io.ErrUnexpectedEOF
3255
+				}
3256
+				b := dAtA[iNdEx]
3257
+				iNdEx++
3258
+				msglen |= (int(b) & 0x7F) << shift
3259
+				if b < 0x80 {
3260
+					break
3261
+				}
3262
+			}
3263
+			if msglen < 0 {
3264
+				return ErrInvalidLengthDispatcher
3265
+			}
3266
+			postIndex := iNdEx + msglen
3267
+			if postIndex > l {
3268
+				return io.ErrUnexpectedEOF
3269
+			}
3270
+			v := &Config{}
3271
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
3272
+				return err
3273
+			}
3274
+			m.Item = &Assignment_Config{v}
3275
+			iNdEx = postIndex
3244 3276
 		default:
3245 3277
 			iNdEx = preIndex
3246 3278
 			skippy, err := skipDispatcher(dAtA[iNdEx:])
... ...
@@ -3630,65 +3780,67 @@ var (
3630 3630
 func init() { proto.RegisterFile("dispatcher.proto", fileDescriptorDispatcher) }
3631 3631
 
3632 3632
 var fileDescriptorDispatcher = []byte{
3633
-	// 949 bytes of a gzipped FileDescriptorProto
3634
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xcd, 0x6e, 0xe3, 0x54,
3635
-	0x14, 0x8e, 0xd3, 0xd4, 0x6d, 0x4f, 0xda, 0x12, 0x2e, 0xa3, 0xc1, 0x58, 0x9a, 0x34, 0xb8, 0x4c,
3636
-	0x54, 0x69, 0x8a, 0x3b, 0x84, 0x9f, 0x0d, 0x55, 0xa1, 0x69, 0x22, 0x35, 0x9a, 0x49, 0xa7, 0xba,
3637
-	0xcd, 0xcc, 0x2c, 0x23, 0x27, 0x3e, 0xb8, 0x26, 0x8d, 0xaf, 0xf1, 0xbd, 0x99, 0x21, 0x48, 0x48,
3638
-	0x48, 0x30, 0x12, 0x62, 0x85, 0x58, 0x75, 0xc3, 0x2b, 0xf0, 0x1c, 0x15, 0x2b, 0x96, 0xac, 0x0a,
3639
-	0x93, 0x07, 0xe0, 0x01, 0x58, 0x21, 0xdb, 0xd7, 0x49, 0xc8, 0x24, 0x9d, 0xb4, 0xab, 0xc4, 0xe7,
3640
-	0x7c, 0xdf, 0x39, 0x9f, 0xbf, 0x7b, 0x7c, 0x2e, 0xe4, 0x6c, 0x97, 0xfb, 0x96, 0x68, 0x9f, 0x62,
3641
-	0x60, 0xfa, 0x01, 0x13, 0x8c, 0x10, 0x9b, 0xb5, 0x3b, 0x18, 0x98, 0xfc, 0xb9, 0x15, 0x74, 0x3b,
3642
-	0xae, 0x30, 0x9f, 0x7d, 0xa0, 0x67, 0x45, 0xdf, 0x47, 0x1e, 0x03, 0xf4, 0x35, 0xd6, 0xfa, 0x12,
3643
-	0xdb, 0x22, 0x79, 0xbc, 0xe5, 0x30, 0x87, 0x45, 0x7f, 0x77, 0xc2, 0x7f, 0x32, 0xfa, 0x96, 0x7f,
3644
-	0xd6, 0x73, 0x5c, 0x6f, 0x27, 0xfe, 0x91, 0xc1, 0xbc, 0xc3, 0x98, 0x73, 0x86, 0x3b, 0xd1, 0x53,
3645
-	0xab, 0xf7, 0xc5, 0x8e, 0xdd, 0x0b, 0x2c, 0xe1, 0x32, 0x99, 0x37, 0x5e, 0x28, 0xb0, 0x7e, 0x82,
3646
-	0x9c, 0xbb, 0xcc, 0xa3, 0xf8, 0x55, 0x0f, 0xb9, 0x20, 0x55, 0xc8, 0xda, 0xc8, 0xdb, 0x81, 0xeb,
3647
-	0x87, 0x38, 0x4d, 0x29, 0x28, 0x5b, 0xd9, 0xd2, 0xa6, 0xf9, 0xaa, 0x46, 0xf3, 0x88, 0xd9, 0x58,
3648
-	0x19, 0x41, 0xe9, 0x38, 0x8f, 0x6c, 0x03, 0xf0, 0xb8, 0x70, 0xd3, 0xb5, 0xb5, 0x74, 0x41, 0xd9,
3649
-	0x5a, 0x29, 0xaf, 0x0d, 0x2e, 0x37, 0x56, 0x64, 0xbb, 0x5a, 0x85, 0xae, 0x48, 0x40, 0xcd, 0x36,
3650
-	0xbe, 0x4f, 0x0f, 0x75, 0xd4, 0x91, 0x73, 0xcb, 0xc1, 0x89, 0x02, 0xca, 0xd5, 0x05, 0xc8, 0x36,
3651
-	0x64, 0x3c, 0x66, 0x63, 0xd4, 0x28, 0x5b, 0xd2, 0x66, 0xc9, 0xa5, 0x11, 0x8a, 0xec, 0xc2, 0x72,
3652
-	0xd7, 0xf2, 0x2c, 0x07, 0x03, 0xae, 0x2d, 0x14, 0x16, 0xb6, 0xb2, 0xa5, 0xc2, 0x34, 0xc6, 0x53,
3653
-	0x74, 0x9d, 0x53, 0x81, 0xf6, 0x31, 0x62, 0x40, 0x87, 0x0c, 0xf2, 0x14, 0x6e, 0x7b, 0x28, 0x9e,
3654
-	0xb3, 0xa0, 0xd3, 0x6c, 0x31, 0x26, 0xb8, 0x08, 0x2c, 0xbf, 0xd9, 0xc1, 0x3e, 0xd7, 0x32, 0x51,
3655
-	0xad, 0x77, 0xa7, 0xd5, 0xaa, 0x7a, 0xed, 0xa0, 0x1f, 0x59, 0xf3, 0x00, 0xfb, 0xf4, 0x96, 0x2c,
3656
-	0x50, 0x4e, 0xf8, 0x0f, 0xb0, 0xcf, 0x8d, 0xcf, 0x21, 0x77, 0x88, 0x56, 0x20, 0x5a, 0x68, 0x89,
3657
-	0xe4, 0x38, 0xae, 0x65, 0x83, 0x71, 0x0c, 0x6f, 0x8e, 0x55, 0xe0, 0x3e, 0xf3, 0x38, 0x92, 0x4f,
3658
-	0x41, 0xf5, 0x31, 0x70, 0x99, 0x2d, 0x0f, 0xf3, 0x1d, 0x33, 0x9e, 0x0a, 0x33, 0x99, 0x0a, 0xb3,
3659
-	0x22, 0xa7, 0xa2, 0xbc, 0x7c, 0x71, 0xb9, 0x91, 0x3a, 0xff, 0x6b, 0x43, 0xa1, 0x92, 0x62, 0xfc,
3660
-	0x9c, 0x86, 0xb7, 0x1f, 0xfb, 0xb6, 0x25, 0xb0, 0x61, 0xf1, 0xce, 0x89, 0xb0, 0x44, 0x8f, 0xdf,
3661
-	0x48, 0x1b, 0x79, 0x02, 0x4b, 0xbd, 0xa8, 0x50, 0xe2, 0xf9, 0xee, 0x34, 0x9f, 0x66, 0xf4, 0x32,
3662
-	0x47, 0x91, 0x18, 0x41, 0x93, 0x62, 0x3a, 0x83, 0xdc, 0x64, 0x92, 0x6c, 0xc2, 0x92, 0xb0, 0x78,
3663
-	0x67, 0x24, 0x0b, 0x06, 0x97, 0x1b, 0x6a, 0x08, 0xab, 0x55, 0xa8, 0x1a, 0xa6, 0x6a, 0x36, 0xf9,
3664
-	0x04, 0x54, 0x1e, 0x91, 0xe4, 0xd4, 0xe4, 0xa7, 0xe9, 0x19, 0x53, 0x22, 0xd1, 0x86, 0x0e, 0xda,
3665
-	0xab, 0x2a, 0x63, 0xaf, 0x8d, 0x5d, 0x58, 0x0d, 0xa3, 0x37, 0xb3, 0xc8, 0xd8, 0x93, 0xec, 0xe4,
3666
-	0x1b, 0x30, 0x61, 0x31, 0xd4, 0xca, 0x35, 0x25, 0x32, 0x4c, 0x9b, 0x25, 0x90, 0xc6, 0x30, 0xa3,
3667
-	0x0c, 0x64, 0x9f, 0x73, 0xd7, 0xf1, 0xba, 0xe8, 0x89, 0x1b, 0x6a, 0xf8, 0x06, 0x60, 0x54, 0x83,
3668
-	0x98, 0x90, 0x09, 0x4b, 0xcb, 0xc9, 0x99, 0x29, 0xe0, 0x30, 0x45, 0x23, 0x1c, 0xf9, 0x08, 0x54,
3669
-	0x8e, 0xed, 0x00, 0x85, 0xf4, 0x54, 0x9f, 0xc6, 0x38, 0x89, 0x10, 0x87, 0x29, 0x2a, 0xb1, 0x65,
3670
-	0x15, 0x32, 0xae, 0xc0, 0xae, 0xf1, 0x22, 0x0d, 0xb9, 0x51, 0xf3, 0x83, 0x53, 0xcb, 0x73, 0x90,
3671
-	0xec, 0x01, 0x58, 0xc3, 0x98, 0x14, 0x32, 0xf5, 0xa8, 0x46, 0x4c, 0x3a, 0xc6, 0x20, 0x75, 0x50,
3672
-	0xad, 0x76, 0xb4, 0xcb, 0x42, 0x49, 0xeb, 0xa5, 0x8f, 0xaf, 0xe6, 0xc6, 0x5d, 0xc7, 0x02, 0xfb,
3673
-	0x11, 0x99, 0xca, 0x22, 0x46, 0x6b, 0x5c, 0x62, 0x9c, 0x23, 0x45, 0x50, 0x1f, 0x1f, 0x57, 0xf6,
3674
-	0x1b, 0xd5, 0x5c, 0x4a, 0xd7, 0x7f, 0xfa, 0xb5, 0x70, 0x7b, 0x12, 0x21, 0xc7, 0xb2, 0x08, 0x2a,
3675
-	0xad, 0xd6, 0x1f, 0x3d, 0xa9, 0xe6, 0x94, 0xe9, 0x38, 0x8a, 0x5d, 0xf6, 0x0c, 0x8d, 0x7f, 0x95,
3676
-	0xff, 0x1d, 0x64, 0x32, 0x0e, 0x9f, 0x41, 0x26, 0xbc, 0x16, 0x22, 0x0f, 0xd6, 0x4b, 0xf7, 0xae,
3677
-	0x7e, 0x8f, 0x84, 0x65, 0x36, 0xfa, 0x3e, 0xd2, 0x88, 0x48, 0xee, 0x00, 0x58, 0xbe, 0x7f, 0xe6,
3678
-	0x22, 0x6f, 0x0a, 0x16, 0x2f, 0x65, 0xba, 0x22, 0x23, 0x0d, 0x16, 0xa6, 0x03, 0xe4, 0xbd, 0x33,
3679
-	0xc1, 0x9b, 0xae, 0xa7, 0x2d, 0xc4, 0x69, 0x19, 0xa9, 0x79, 0x64, 0x0f, 0x96, 0xda, 0x91, 0x39,
3680
-	0xc9, 0xa2, 0x7b, 0x6f, 0x1e, 0x27, 0x69, 0x42, 0x32, 0xee, 0x42, 0x26, 0xd4, 0x42, 0x56, 0x61,
3681
-	0xf9, 0xe0, 0x51, 0xfd, 0xf8, 0x61, 0x35, 0xf4, 0x8b, 0xbc, 0x01, 0xd9, 0xda, 0xd1, 0x01, 0xad,
3682
-	0xd6, 0xab, 0x47, 0x8d, 0xfd, 0x87, 0x39, 0xa5, 0x74, 0xbe, 0x08, 0x50, 0x19, 0xde, 0x91, 0xe4,
3683
-	0x6b, 0x58, 0x92, 0x73, 0x4a, 0x8c, 0xe9, 0xc3, 0x34, 0x7e, 0x7d, 0xe9, 0x57, 0x61, 0xa4, 0x23,
3684
-	0xc6, 0xe6, 0xef, 0xbf, 0xfd, 0x73, 0x9e, 0xbe, 0x03, 0xab, 0x11, 0xe6, 0xfd, 0x70, 0x11, 0x63,
3685
-	0x00, 0x6b, 0xf1, 0x93, 0x5c, 0xf3, 0xf7, 0x15, 0xf2, 0x2d, 0xac, 0x0c, 0x97, 0x29, 0x99, 0xfa,
3686
-	0xae, 0x93, 0xdb, 0x5a, 0xbf, 0xfb, 0x1a, 0x94, 0xdc, 0x12, 0xf3, 0x08, 0x20, 0xbf, 0x28, 0x90,
3687
-	0x9b, 0xdc, 0x33, 0xe4, 0xde, 0x35, 0x76, 0xa6, 0xbe, 0x3d, 0x1f, 0xf8, 0x3a, 0xa2, 0x7a, 0xb0,
3688
-	0x18, 0x6d, 0x28, 0x52, 0x98, 0xb5, 0x0a, 0x86, 0xdd, 0x67, 0x23, 0x92, 0x73, 0x28, 0xce, 0xd1,
3689
-	0xf1, 0xc7, 0xb4, 0x72, 0x5f, 0x21, 0x3f, 0x28, 0x90, 0x1d, 0x1b, 0x6d, 0x52, 0x7c, 0xcd, 0xec,
3690
-	0x27, 0x1a, 0x8a, 0xf3, 0x7d, 0x23, 0x73, 0x4e, 0x44, 0x59, 0xbb, 0x78, 0x99, 0x4f, 0xfd, 0xf9,
3691
-	0x32, 0x9f, 0xfa, 0x6e, 0x90, 0x57, 0x2e, 0x06, 0x79, 0xe5, 0x8f, 0x41, 0x5e, 0xf9, 0x7b, 0x90,
3692
-	0x57, 0x5a, 0x6a, 0x74, 0x97, 0x7e, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0xa6, 0xd5,
3693
-	0x2c, 0xde, 0x09, 0x00, 0x00,
3633
+	// 983 bytes of a gzipped FileDescriptorProto
3634
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0x4f, 0x6f, 0x1b, 0x45,
3635
+	0x14, 0xf7, 0x38, 0xce, 0x26, 0x7e, 0x4e, 0x82, 0x19, 0xaa, 0xb0, 0xac, 0x54, 0xc7, 0x6c, 0x68,
3636
+	0x14, 0xa9, 0x61, 0x53, 0xcc, 0x9f, 0x0b, 0x51, 0x20, 0x8e, 0x2d, 0xc5, 0x6a, 0x93, 0x46, 0x13,
3637
+	0xb7, 0x3d, 0x5a, 0x6b, 0xef, 0x74, 0xb3, 0x38, 0xde, 0x59, 0x76, 0xc6, 0x2d, 0x3e, 0x20, 0x71,
3638
+	0xa0, 0x12, 0xe2, 0x84, 0x38, 0x45, 0x42, 0x7c, 0x05, 0xc4, 0xc7, 0x88, 0x38, 0x71, 0xe4, 0x14,
3639
+	0xa8, 0x3f, 0x00, 0x1f, 0x80, 0x13, 0xda, 0xd9, 0x59, 0xdb, 0x75, 0xed, 0xd4, 0xc9, 0xc9, 0x9e,
3640
+	0x37, 0xbf, 0xdf, 0x9b, 0xdf, 0xbc, 0xf7, 0xdb, 0x37, 0x90, 0x77, 0x3c, 0x1e, 0xd8, 0xa2, 0x75,
3641
+	0x4a, 0x43, 0x2b, 0x08, 0x99, 0x60, 0x18, 0x3b, 0xac, 0xd5, 0xa6, 0xa1, 0xc5, 0x9f, 0xdb, 0x61,
3642
+	0xa7, 0xed, 0x09, 0xeb, 0xd9, 0x47, 0x46, 0x4e, 0xf4, 0x02, 0xca, 0x63, 0x80, 0xb1, 0xcc, 0x9a,
3643
+	0x5f, 0xd1, 0x96, 0x48, 0x96, 0xb7, 0x5c, 0xe6, 0x32, 0xf9, 0x77, 0x3b, 0xfa, 0xa7, 0xa2, 0xef,
3644
+	0x04, 0x67, 0x5d, 0xd7, 0xf3, 0xb7, 0xe3, 0x1f, 0x15, 0x2c, 0xb8, 0x8c, 0xb9, 0x67, 0x74, 0x5b,
3645
+	0xae, 0x9a, 0xdd, 0xa7, 0xdb, 0x4e, 0x37, 0xb4, 0x85, 0xc7, 0xd4, 0xbe, 0xf9, 0x02, 0xc1, 0xca,
3646
+	0x09, 0xe5, 0xdc, 0x63, 0x3e, 0xa1, 0x5f, 0x77, 0x29, 0x17, 0xb8, 0x0a, 0x39, 0x87, 0xf2, 0x56,
3647
+	0xe8, 0x05, 0x11, 0x4e, 0x47, 0x45, 0xb4, 0x99, 0x2b, 0xad, 0x5b, 0xaf, 0x6b, 0xb4, 0x8e, 0x98,
3648
+	0x43, 0x2b, 0x43, 0x28, 0x19, 0xe5, 0xe1, 0x2d, 0x00, 0x1e, 0x27, 0x6e, 0x78, 0x8e, 0x9e, 0x2e,
3649
+	0xa2, 0xcd, 0x6c, 0x79, 0xb9, 0x7f, 0xb9, 0x96, 0x55, 0xc7, 0xd5, 0x2a, 0x24, 0xab, 0x00, 0x35,
3650
+	0xc7, 0xfc, 0x25, 0x3d, 0xd0, 0x71, 0x48, 0x39, 0xb7, 0x5d, 0x3a, 0x96, 0x00, 0x5d, 0x9d, 0x00,
3651
+	0x6f, 0x41, 0xc6, 0x67, 0x0e, 0x95, 0x07, 0xe5, 0x4a, 0xfa, 0x34, 0xb9, 0x44, 0xa2, 0xf0, 0x0e,
3652
+	0x2c, 0x76, 0x6c, 0xdf, 0x76, 0x69, 0xc8, 0xf5, 0xb9, 0xe2, 0xdc, 0x66, 0xae, 0x54, 0x9c, 0xc4,
3653
+	0x78, 0x42, 0x3d, 0xf7, 0x54, 0x50, 0xe7, 0x98, 0xd2, 0x90, 0x0c, 0x18, 0xf8, 0x09, 0xac, 0xfa,
3654
+	0x54, 0x3c, 0x67, 0x61, 0xbb, 0xd1, 0x64, 0x4c, 0x70, 0x11, 0xda, 0x41, 0xa3, 0x4d, 0x7b, 0x5c,
3655
+	0xcf, 0xc8, 0x5c, 0xef, 0x4f, 0xca, 0x55, 0xf5, 0x5b, 0x61, 0x4f, 0x96, 0xe6, 0x3e, 0xed, 0x91,
3656
+	0x5b, 0x2a, 0x41, 0x39, 0xe1, 0xdf, 0xa7, 0x3d, 0x8e, 0x57, 0x41, 0x23, 0x8c, 0x89, 0xfd, 0x3d,
3657
+	0x7d, 0xbe, 0x88, 0x36, 0x97, 0x88, 0x5a, 0x99, 0x5f, 0x42, 0xfe, 0x80, 0xda, 0xa1, 0x68, 0x52,
3658
+	0x5b, 0x24, 0x6d, 0xba, 0x56, 0x79, 0xcc, 0x63, 0x78, 0x7b, 0x24, 0x03, 0x0f, 0x98, 0xcf, 0x29,
3659
+	0xfe, 0x1c, 0xb4, 0x80, 0x86, 0x1e, 0x73, 0x54, 0x93, 0xdf, 0xb3, 0x62, 0xb7, 0x58, 0x89, 0x5b,
3660
+	0xac, 0x8a, 0x72, 0x4b, 0x79, 0xf1, 0xe2, 0x72, 0x2d, 0x75, 0xfe, 0xf7, 0x1a, 0x22, 0x8a, 0x62,
3661
+	0xfe, 0x94, 0x86, 0x77, 0x1f, 0x05, 0x8e, 0x2d, 0x68, 0xdd, 0xe6, 0xed, 0x13, 0x61, 0x8b, 0x2e,
3662
+	0xbf, 0x91, 0x36, 0xfc, 0x18, 0x16, 0xba, 0x32, 0x51, 0xd2, 0x8b, 0x9d, 0x49, 0xf5, 0x9b, 0x72,
3663
+	0x96, 0x35, 0x8c, 0xc4, 0x08, 0x92, 0x24, 0x33, 0x18, 0xe4, 0xc7, 0x37, 0xf1, 0x3a, 0x2c, 0x08,
3664
+	0x9b, 0xb7, 0x87, 0xb2, 0xa0, 0x7f, 0xb9, 0xa6, 0x45, 0xb0, 0x5a, 0x85, 0x68, 0xd1, 0x56, 0xcd,
3665
+	0xc1, 0x9f, 0x81, 0xc6, 0x25, 0x49, 0xb9, 0xa9, 0x30, 0x49, 0xcf, 0x88, 0x12, 0x85, 0x36, 0x0d,
3666
+	0xd0, 0x5f, 0x57, 0x19, 0xd7, 0xda, 0xdc, 0x81, 0xa5, 0x28, 0x7a, 0xb3, 0x12, 0x99, 0xbb, 0x8a,
3667
+	0x9d, 0x7c, 0x1b, 0x16, 0xcc, 0x47, 0x5a, 0xb9, 0x8e, 0x64, 0xc1, 0xf4, 0x69, 0x02, 0x49, 0x0c,
3668
+	0x33, 0xcb, 0x80, 0xf7, 0x38, 0xf7, 0x5c, 0xbf, 0x43, 0x7d, 0x71, 0x43, 0x0d, 0xbf, 0x23, 0x80,
3669
+	0x61, 0x12, 0x6c, 0x41, 0x26, 0xca, 0xad, 0xac, 0x33, 0x55, 0xc1, 0x41, 0x8a, 0x48, 0x1c, 0xfe,
3670
+	0x04, 0x34, 0x4e, 0x5b, 0x21, 0x15, 0xaa, 0xa8, 0xc6, 0x24, 0xc6, 0x89, 0x44, 0x1c, 0xa4, 0x88,
3671
+	0xc2, 0x46, 0xac, 0x16, 0xf3, 0x9f, 0x7a, 0xae, 0x3e, 0x37, 0x9d, 0xb5, 0x2f, 0x11, 0x11, 0x2b,
3672
+	0xc6, 0x96, 0x35, 0xc8, 0x78, 0x82, 0x76, 0xcc, 0x17, 0x69, 0xc8, 0x0f, 0x25, 0xef, 0x9f, 0xda,
3673
+	0xbe, 0x4b, 0xf1, 0x2e, 0x80, 0x3d, 0x88, 0x29, 0xf9, 0x13, 0x3b, 0x3c, 0x64, 0x92, 0x11, 0x06,
3674
+	0x3e, 0x04, 0xcd, 0x6e, 0xc9, 0xd1, 0x18, 0x5d, 0x64, 0xa5, 0xf4, 0xe9, 0xd5, 0xdc, 0xf8, 0xd4,
3675
+	0x91, 0xc0, 0x9e, 0x24, 0x13, 0x95, 0xc4, 0x6c, 0x8e, 0x4a, 0x8c, 0xf7, 0xf0, 0x06, 0x68, 0x8f,
3676
+	0x8e, 0x2b, 0x7b, 0xf5, 0x6a, 0x3e, 0x65, 0x18, 0x3f, 0xfe, 0x5a, 0x5c, 0x1d, 0x47, 0x28, 0x37,
3677
+	0x6f, 0x80, 0x46, 0xaa, 0x87, 0x0f, 0x1f, 0x57, 0xf3, 0x68, 0x32, 0x8e, 0xd0, 0x0e, 0x7b, 0x46,
3678
+	0xcd, 0xff, 0xd0, 0x2b, 0xfd, 0x4f, 0x5c, 0xf4, 0x05, 0x64, 0xa2, 0x57, 0x46, 0xd6, 0x60, 0xa5,
3679
+	0x74, 0xf7, 0xea, 0x7b, 0x24, 0x2c, 0xab, 0xde, 0x0b, 0x28, 0x91, 0x44, 0x7c, 0x1b, 0xc0, 0x0e,
3680
+	0x82, 0x33, 0x8f, 0xf2, 0x86, 0x60, 0xf1, 0x8c, 0x27, 0x59, 0x15, 0xa9, 0xb3, 0x68, 0x3b, 0xa4,
3681
+	0xbc, 0x7b, 0x26, 0x78, 0xc3, 0xf3, 0x65, 0x03, 0xb3, 0x24, 0xab, 0x22, 0x35, 0x1f, 0xef, 0xc2,
3682
+	0x42, 0x4b, 0x16, 0x27, 0x99, 0x9b, 0x1f, 0xcc, 0x52, 0x49, 0x92, 0x90, 0xcc, 0x3b, 0x90, 0x89,
3683
+	0xb4, 0xe0, 0x25, 0x58, 0xdc, 0x7f, 0x78, 0x78, 0xfc, 0xa0, 0x1a, 0xd5, 0x0b, 0xbf, 0x05, 0xb9,
3684
+	0xda, 0xd1, 0x3e, 0xa9, 0x1e, 0x56, 0x8f, 0xea, 0x7b, 0x0f, 0xf2, 0xa8, 0x74, 0x3e, 0x0f, 0x50,
3685
+	0x19, 0x3c, 0xb9, 0xf8, 0x1b, 0x58, 0x50, 0xf6, 0xc6, 0xe6, 0x64, 0x0b, 0x8e, 0xbe, 0x86, 0xc6,
3686
+	0x55, 0x18, 0x55, 0x11, 0x73, 0xfd, 0x8f, 0xdf, 0xfe, 0x3d, 0x4f, 0xdf, 0x86, 0x25, 0x89, 0xf9,
3687
+	0x30, 0x9a, 0xeb, 0x34, 0x84, 0xe5, 0x78, 0xa5, 0x5e, 0x8d, 0x7b, 0x08, 0x7f, 0x0b, 0xd9, 0xc1,
3688
+	0x0c, 0xc6, 0x13, 0xef, 0x3a, 0x3e, 0xe4, 0x8d, 0x3b, 0x6f, 0x40, 0xa9, 0xe1, 0x32, 0x8b, 0x00,
3689
+	0xfc, 0x33, 0x82, 0xfc, 0xf8, 0x78, 0xc2, 0x77, 0xaf, 0x31, 0x6a, 0x8d, 0xad, 0xd9, 0xc0, 0xd7,
3690
+	0x11, 0xd5, 0x85, 0x79, 0x39, 0xd8, 0x70, 0x71, 0xda, 0x00, 0x19, 0x9c, 0x3e, 0x1d, 0x91, 0xf4,
3691
+	0x61, 0x63, 0x86, 0x13, 0x7f, 0x48, 0xa3, 0x7b, 0x08, 0x7f, 0x8f, 0x20, 0x37, 0x62, 0x6d, 0xbc,
3692
+	0xf1, 0x06, 0xef, 0x27, 0x1a, 0x36, 0x66, 0xfb, 0x46, 0x66, 0x74, 0x44, 0x59, 0xbf, 0x78, 0x59,
3693
+	0x48, 0xfd, 0xf5, 0xb2, 0x90, 0xfa, 0xae, 0x5f, 0x40, 0x17, 0xfd, 0x02, 0xfa, 0xb3, 0x5f, 0x40,
3694
+	0xff, 0xf4, 0x0b, 0xa8, 0xa9, 0xc9, 0x27, 0xf8, 0xe3, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x6c,
3695
+	0xba, 0x38, 0xbd, 0x2d, 0x0a, 0x00, 0x00,
3694 3696
 }
... ...
@@ -126,6 +126,9 @@ message SessionMessage {
126 126
 	// Symmetric encryption key distributed by the lead manager. Used by agents
127 127
 	// for securing network bootstrapping and communication.
128 128
 	repeated EncryptionKey network_bootstrap_keys = 4;
129
+
130
+	// Which root certificates to trust
131
+	bytes RootCA = 5;
129 132
 }
130 133
 
131 134
 // HeartbeatRequest provides identifying properties for a single heartbeat.
... ...
@@ -174,6 +177,7 @@ message Assignment {
174 174
 	oneof item {
175 175
 		Task task = 1;
176 176
 		Secret secret = 2;
177
+		Config config = 3;
177 178
 	}
178 179
 }
179 180
 
... ...
@@ -269,9 +269,7 @@ func (*Cluster) ProtoMessage()               {}
269 269
 func (*Cluster) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{7} }
270 270
 
271 271
 // Secret represents a secret that should be passed to a container or a node,
272
-// and is immutable. It wraps the `spec` provided by the user with useful
273
-// information that is generated from the secret data in the `spec`, such as
274
-// the digest and size of the secret data.
272
+// and is immutable.
275 273
 type Secret struct {
276 274
 	ID   string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
277 275
 	Meta Meta   `protobuf:"bytes,2,opt,name=meta" json:"meta"`
... ...
@@ -286,6 +284,20 @@ func (m *Secret) Reset()                    { *m = Secret{} }
286 286
 func (*Secret) ProtoMessage()               {}
287 287
 func (*Secret) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{8} }
288 288
 
289
+// Config represents a set of configuration files that should be passed to a
290
+// container.
291
+type Config struct {
292
+	ID   string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
293
+	Meta Meta   `protobuf:"bytes,2,opt,name=meta" json:"meta"`
294
+	// Spec contains the actual config data, as well as any context around the
295
+	// config data that the user provides.
296
+	Spec ConfigSpec `protobuf:"bytes,3,opt,name=spec" json:"spec"`
297
+}
298
+
299
+func (m *Config) Reset()                    { *m = Config{} }
300
+func (*Config) ProtoMessage()               {}
301
+func (*Config) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{9} }
302
+
289 303
 // Resource is a top-level object with externally defined content and indexing.
290 304
 // SwarmKit can serve as a store for these objects without understanding their
291 305
 // meanings.
... ...
@@ -304,7 +316,7 @@ type Resource struct {
304 304
 
305 305
 func (m *Resource) Reset()                    { *m = Resource{} }
306 306
 func (*Resource) ProtoMessage()               {}
307
-func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{9} }
307
+func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{10} }
308 308
 
309 309
 // Extension declares a type of "resource" object. This message provides some
310 310
 // metadata about the objects.
... ...
@@ -317,7 +329,7 @@ type Extension struct {
317 317
 
318 318
 func (m *Extension) Reset()                    { *m = Extension{} }
319 319
 func (*Extension) ProtoMessage()               {}
320
-func (*Extension) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{10} }
320
+func (*Extension) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{11} }
321 321
 
322 322
 func init() {
323 323
 	proto.RegisterType((*Meta)(nil), "docker.swarmkit.v1.Meta")
... ...
@@ -330,6 +342,7 @@ func init() {
330 330
 	proto.RegisterType((*Network)(nil), "docker.swarmkit.v1.Network")
331 331
 	proto.RegisterType((*Cluster)(nil), "docker.swarmkit.v1.Cluster")
332 332
 	proto.RegisterType((*Secret)(nil), "docker.swarmkit.v1.Secret")
333
+	proto.RegisterType((*Config)(nil), "docker.swarmkit.v1.Config")
333 334
 	proto.RegisterType((*Resource)(nil), "docker.swarmkit.v1.Resource")
334 335
 	proto.RegisterType((*Extension)(nil), "docker.swarmkit.v1.Extension")
335 336
 }
... ...
@@ -629,6 +642,23 @@ func (m *Secret) CopyFrom(src interface{}) {
629 629
 	github_com_docker_swarmkit_api_deepcopy.Copy(&m.Spec, &o.Spec)
630 630
 }
631 631
 
632
+func (m *Config) Copy() *Config {
633
+	if m == nil {
634
+		return nil
635
+	}
636
+	o := &Config{}
637
+	o.CopyFrom(m)
638
+	return o
639
+}
640
+
641
+func (m *Config) CopyFrom(src interface{}) {
642
+
643
+	o := src.(*Config)
644
+	*m = *o
645
+	github_com_docker_swarmkit_api_deepcopy.Copy(&m.Meta, &o.Meta)
646
+	github_com_docker_swarmkit_api_deepcopy.Copy(&m.Spec, &o.Spec)
647
+}
648
+
632 649
 func (m *Resource) Copy() *Resource {
633 650
 	if m == nil {
634 651
 		return nil
... ...
@@ -1377,7 +1407,7 @@ func (m *Secret) MarshalTo(dAtA []byte) (int, error) {
1377 1377
 	return i, nil
1378 1378
 }
1379 1379
 
1380
-func (m *Resource) Marshal() (dAtA []byte, err error) {
1380
+func (m *Config) Marshal() (dAtA []byte, err error) {
1381 1381
 	size := m.Size()
1382 1382
 	dAtA = make([]byte, size)
1383 1383
 	n, err := m.MarshalTo(dAtA)
... ...
@@ -1387,7 +1417,7 @@ func (m *Resource) Marshal() (dAtA []byte, err error) {
1387 1387
 	return dAtA[:n], nil
1388 1388
 }
1389 1389
 
1390
-func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
1390
+func (m *Config) MarshalTo(dAtA []byte) (int, error) {
1391 1391
 	var i int
1392 1392
 	_ = i
1393 1393
 	var l int
... ...
@@ -1408,12 +1438,52 @@ func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
1408 1408
 	i += n38
1409 1409
 	dAtA[i] = 0x1a
1410 1410
 	i++
1411
-	i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
1412
-	n39, err := m.Annotations.MarshalTo(dAtA[i:])
1411
+	i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
1412
+	n39, err := m.Spec.MarshalTo(dAtA[i:])
1413 1413
 	if err != nil {
1414 1414
 		return 0, err
1415 1415
 	}
1416 1416
 	i += n39
1417
+	return i, nil
1418
+}
1419
+
1420
+func (m *Resource) Marshal() (dAtA []byte, err error) {
1421
+	size := m.Size()
1422
+	dAtA = make([]byte, size)
1423
+	n, err := m.MarshalTo(dAtA)
1424
+	if err != nil {
1425
+		return nil, err
1426
+	}
1427
+	return dAtA[:n], nil
1428
+}
1429
+
1430
+func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
1431
+	var i int
1432
+	_ = i
1433
+	var l int
1434
+	_ = l
1435
+	if len(m.ID) > 0 {
1436
+		dAtA[i] = 0xa
1437
+		i++
1438
+		i = encodeVarintObjects(dAtA, i, uint64(len(m.ID)))
1439
+		i += copy(dAtA[i:], m.ID)
1440
+	}
1441
+	dAtA[i] = 0x12
1442
+	i++
1443
+	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
1444
+	n40, err := m.Meta.MarshalTo(dAtA[i:])
1445
+	if err != nil {
1446
+		return 0, err
1447
+	}
1448
+	i += n40
1449
+	dAtA[i] = 0x1a
1450
+	i++
1451
+	i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
1452
+	n41, err := m.Annotations.MarshalTo(dAtA[i:])
1453
+	if err != nil {
1454
+		return 0, err
1455
+	}
1456
+	i += n41
1417 1457
 	if len(m.Kind) > 0 {
1418 1458
 		dAtA[i] = 0x22
1419 1459
 		i++
... ...
@@ -1424,11 +1494,11 @@ func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
1424 1424
 		dAtA[i] = 0x2a
1425 1425
 		i++
1426 1426
 		i = encodeVarintObjects(dAtA, i, uint64(m.Payload.Size()))
1427
-		n40, err := m.Payload.MarshalTo(dAtA[i:])
1427
+		n42, err := m.Payload.MarshalTo(dAtA[i:])
1428 1428
 		if err != nil {
1429 1429
 			return 0, err
1430 1430
 		}
1431
-		i += n40
1431
+		i += n42
1432 1432
 	}
1433 1433
 	return i, nil
1434 1434
 }
... ...
@@ -1457,19 +1527,19 @@ func (m *Extension) MarshalTo(dAtA []byte) (int, error) {
1457 1457
 	dAtA[i] = 0x12
1458 1458
 	i++
1459 1459
 	i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
1460
-	n41, err := m.Meta.MarshalTo(dAtA[i:])
1460
+	n43, err := m.Meta.MarshalTo(dAtA[i:])
1461 1461
 	if err != nil {
1462 1462
 		return 0, err
1463 1463
 	}
1464
-	i += n41
1464
+	i += n43
1465 1465
 	dAtA[i] = 0x1a
1466 1466
 	i++
1467 1467
 	i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
1468
-	n42, err := m.Annotations.MarshalTo(dAtA[i:])
1468
+	n44, err := m.Annotations.MarshalTo(dAtA[i:])
1469 1469
 	if err != nil {
1470 1470
 		return 0, err
1471 1471
 	}
1472
-	i += n42
1472
+	i += n44
1473 1473
 	if len(m.Description) > 0 {
1474 1474
 		dAtA[i] = 0x22
1475 1475
 		i++
... ...
@@ -1783,6 +1853,20 @@ func (m *Secret) Size() (n int) {
1783 1783
 	return n
1784 1784
 }
1785 1785
 
1786
+func (m *Config) Size() (n int) {
1787
+	var l int
1788
+	_ = l
1789
+	l = len(m.ID)
1790
+	if l > 0 {
1791
+		n += 1 + l + sovObjects(uint64(l))
1792
+	}
1793
+	l = m.Meta.Size()
1794
+	n += 1 + l + sovObjects(uint64(l))
1795
+	l = m.Spec.Size()
1796
+	n += 1 + l + sovObjects(uint64(l))
1797
+	return n
1798
+}
1799
+
1786 1800
 func (m *Resource) Size() (n int) {
1787 1801
 	var l int
1788 1802
 	_ = l
... ...
@@ -3212,6 +3296,223 @@ func (indexer SecretCustomIndexer) FromObject(obj interface{}) (bool, [][]byte,
3212 3212
 	return customIndexer("", &m.Spec.Annotations)
3213 3213
 }
3214 3214
 
3215
+type ConfigCheckFunc func(t1, t2 *Config) bool
3216
+
3217
+type EventCreateConfig struct {
3218
+	Config *Config
3219
+	Checks []ConfigCheckFunc
3220
+}
3221
+
3222
+func (e EventCreateConfig) Matches(apiEvent github_com_docker_go_events.Event) bool {
3223
+	typedEvent, ok := apiEvent.(EventCreateConfig)
3224
+	if !ok {
3225
+		return false
3226
+	}
3227
+
3228
+	for _, check := range e.Checks {
3229
+		if !check(e.Config, typedEvent.Config) {
3230
+			return false
3231
+		}
3232
+	}
3233
+	return true
3234
+}
3235
+
3236
+type EventUpdateConfig struct {
3237
+	Config    *Config
3238
+	OldConfig *Config
3239
+	Checks    []ConfigCheckFunc
3240
+}
3241
+
3242
+func (e EventUpdateConfig) Matches(apiEvent github_com_docker_go_events.Event) bool {
3243
+	typedEvent, ok := apiEvent.(EventUpdateConfig)
3244
+	if !ok {
3245
+		return false
3246
+	}
3247
+
3248
+	for _, check := range e.Checks {
3249
+		if !check(e.Config, typedEvent.Config) {
3250
+			return false
3251
+		}
3252
+	}
3253
+	return true
3254
+}
3255
+
3256
+type EventDeleteConfig struct {
3257
+	Config *Config
3258
+	Checks []ConfigCheckFunc
3259
+}
3260
+
3261
+func (e EventDeleteConfig) Matches(apiEvent github_com_docker_go_events.Event) bool {
3262
+	typedEvent, ok := apiEvent.(EventDeleteConfig)
3263
+	if !ok {
3264
+		return false
3265
+	}
3266
+
3267
+	for _, check := range e.Checks {
3268
+		if !check(e.Config, typedEvent.Config) {
3269
+			return false
3270
+		}
3271
+	}
3272
+	return true
3273
+}
3274
+func (m *Config) CopyStoreObject() StoreObject {
3275
+	return m.Copy()
3276
+}
3277
+
3278
+func (m *Config) GetMeta() Meta {
3279
+	return m.Meta
3280
+}
3281
+
3282
+func (m *Config) SetMeta(meta Meta) {
3283
+	m.Meta = meta
3284
+}
3285
+
3286
+func (m *Config) GetID() string {
3287
+	return m.ID
3288
+}
3289
+
3290
+func (m *Config) EventCreate() Event {
3291
+	return EventCreateConfig{Config: m}
3292
+}
3293
+
3294
+func (m *Config) EventUpdate(oldObject StoreObject) Event {
3295
+	if oldObject != nil {
3296
+		return EventUpdateConfig{Config: m, OldConfig: oldObject.(*Config)}
3297
+	} else {
3298
+		return EventUpdateConfig{Config: m}
3299
+	}
3300
+}
3301
+
3302
+func (m *Config) EventDelete() Event {
3303
+	return EventDeleteConfig{Config: m}
3304
+}
3305
+
3306
+func ConfigCheckID(v1, v2 *Config) bool {
3307
+	return v1.ID == v2.ID
3308
+}
3309
+
3310
+func ConfigCheckIDPrefix(v1, v2 *Config) bool {
3311
+	return strings.HasPrefix(v2.ID, v1.ID)
3312
+}
3313
+
3314
+func ConfigCheckName(v1, v2 *Config) bool {
3315
+	return v1.Spec.Annotations.Name == v2.Spec.Annotations.Name
3316
+}
3317
+
3318
+func ConfigCheckNamePrefix(v1, v2 *Config) bool {
3319
+	return strings.HasPrefix(v2.Spec.Annotations.Name, v1.Spec.Annotations.Name)
3320
+}
3321
+
3322
+func ConfigCheckCustom(v1, v2 *Config) bool {
3323
+	return checkCustom(v1.Spec.Annotations, v2.Spec.Annotations)
3324
+}
3325
+
3326
+func ConfigCheckCustomPrefix(v1, v2 *Config) bool {
3327
+	return checkCustomPrefix(v1.Spec.Annotations, v2.Spec.Annotations)
3328
+}
3329
+
3330
+func ConvertConfigWatch(action WatchActionKind, filters []*SelectBy) ([]Event, error) {
3331
+	var (
3332
+		m          Config
3333
+		checkFuncs []ConfigCheckFunc
3334
+	)
3335
+
3336
+	for _, filter := range filters {
3337
+		switch v := filter.By.(type) {
3338
+		case *SelectBy_ID:
3339
+			if m.ID != "" {
3340
+				return nil, errConflictingFilters
3341
+			}
3342
+			m.ID = v.ID
3343
+			checkFuncs = append(checkFuncs, ConfigCheckID)
3344
+		case *SelectBy_IDPrefix:
3345
+			if m.ID != "" {
3346
+				return nil, errConflictingFilters
3347
+			}
3348
+			m.ID = v.IDPrefix
3349
+			checkFuncs = append(checkFuncs, ConfigCheckIDPrefix)
3350
+		case *SelectBy_Name:
3351
+			if m.Spec.Annotations.Name != "" {
3352
+				return nil, errConflictingFilters
3353
+			}
3354
+			m.Spec.Annotations.Name = v.Name
3355
+			checkFuncs = append(checkFuncs, ConfigCheckName)
3356
+		case *SelectBy_NamePrefix:
3357
+			if m.Spec.Annotations.Name != "" {
3358
+				return nil, errConflictingFilters
3359
+			}
3360
+			m.Spec.Annotations.Name = v.NamePrefix
3361
+			checkFuncs = append(checkFuncs, ConfigCheckNamePrefix)
3362
+		case *SelectBy_Custom:
3363
+			if len(m.Spec.Annotations.Indices) != 0 {
3364
+				return nil, errConflictingFilters
3365
+			}
3366
+			m.Spec.Annotations.Indices = []IndexEntry{{Key: v.Custom.Index, Val: v.Custom.Value}}
3367
+			checkFuncs = append(checkFuncs, ConfigCheckCustom)
3368
+		case *SelectBy_CustomPrefix:
3369
+			if len(m.Spec.Annotations.Indices) != 0 {
3370
+				return nil, errConflictingFilters
3371
+			}
3372
+			m.Spec.Annotations.Indices = []IndexEntry{{Key: v.CustomPrefix.Index, Val: v.CustomPrefix.Value}}
3373
+			checkFuncs = append(checkFuncs, ConfigCheckCustomPrefix)
3374
+		}
3375
+	}
3376
+	var events []Event
3377
+	if (action & WatchActionKindCreate) != 0 {
3378
+		events = append(events, EventCreateConfig{Config: &m, Checks: checkFuncs})
3379
+	}
3380
+	if (action & WatchActionKindUpdate) != 0 {
3381
+		events = append(events, EventUpdateConfig{Config: &m, Checks: checkFuncs})
3382
+	}
3383
+	if (action & WatchActionKindRemove) != 0 {
3384
+		events = append(events, EventDeleteConfig{Config: &m, Checks: checkFuncs})
3385
+	}
3386
+	if len(events) == 0 {
3387
+		return nil, errUnrecognizedAction
3388
+	}
3389
+	return events, nil
3390
+}
3391
+
3392
+type ConfigIndexerByID struct{}
3393
+
3394
+func (indexer ConfigIndexerByID) FromArgs(args ...interface{}) ([]byte, error) {
3395
+	return fromArgs(args...)
3396
+}
3397
+func (indexer ConfigIndexerByID) PrefixFromArgs(args ...interface{}) ([]byte, error) {
3398
+	return prefixFromArgs(args...)
3399
+}
3400
+func (indexer ConfigIndexerByID) FromObject(obj interface{}) (bool, []byte, error) {
3401
+	m := obj.(*Config)
3402
+	return true, []byte(m.ID + "\x00"), nil
3403
+}
3404
+
3405
+type ConfigIndexerByName struct{}
3406
+
3407
+func (indexer ConfigIndexerByName) FromArgs(args ...interface{}) ([]byte, error) {
3408
+	return fromArgs(args...)
3409
+}
3410
+func (indexer ConfigIndexerByName) PrefixFromArgs(args ...interface{}) ([]byte, error) {
3411
+	return prefixFromArgs(args...)
3412
+}
3413
+func (indexer ConfigIndexerByName) FromObject(obj interface{}) (bool, []byte, error) {
3414
+	m := obj.(*Config)
3415
+	val := m.Spec.Annotations.Name
3416
+	return true, []byte(strings.ToLower(val) + "\x00"), nil
3417
+}
3418
+
3419
+type ConfigCustomIndexer struct{}
3420
+
3421
+func (indexer ConfigCustomIndexer) FromArgs(args ...interface{}) ([]byte, error) {
3422
+	return fromArgs(args...)
3423
+}
3424
+func (indexer ConfigCustomIndexer) PrefixFromArgs(args ...interface{}) ([]byte, error) {
3425
+	return prefixFromArgs(args...)
3426
+}
3427
+func (indexer ConfigCustomIndexer) FromObject(obj interface{}) (bool, [][]byte, error) {
3428
+	m := obj.(*Config)
3429
+	return customIndexer("", &m.Spec.Annotations)
3430
+}
3431
+
3215 3432
 type ResourceCheckFunc func(t1, t2 *Resource) bool
3216 3433
 
3217 3434
 type EventCreateResource struct {
... ...
@@ -3708,6 +4009,15 @@ func NewStoreAction(c Event) (StoreAction, error) {
3708 3708
 	case EventDeleteSecret:
3709 3709
 		sa.Action = StoreActionKindRemove
3710 3710
 		sa.Target = &StoreAction_Secret{Secret: v.Secret}
3711
+	case EventCreateConfig:
3712
+		sa.Action = StoreActionKindCreate
3713
+		sa.Target = &StoreAction_Config{Config: v.Config}
3714
+	case EventUpdateConfig:
3715
+		sa.Action = StoreActionKindUpdate
3716
+		sa.Target = &StoreAction_Config{Config: v.Config}
3717
+	case EventDeleteConfig:
3718
+		sa.Action = StoreActionKindRemove
3719
+		sa.Target = &StoreAction_Config{Config: v.Config}
3711 3720
 	case EventCreateResource:
3712 3721
 		sa.Action = StoreActionKindCreate
3713 3722
 		sa.Target = &StoreAction_Resource{Resource: v.Resource}
... ...
@@ -3812,6 +4122,19 @@ func EventFromStoreAction(sa StoreAction, oldObject StoreObject) (Event, error)
3812 3812
 		case StoreActionKindRemove:
3813 3813
 			return EventDeleteSecret{Secret: v.Secret}, nil
3814 3814
 		}
3815
+	case *StoreAction_Config:
3816
+		switch sa.Action {
3817
+		case StoreActionKindCreate:
3818
+			return EventCreateConfig{Config: v.Config}, nil
3819
+		case StoreActionKindUpdate:
3820
+			if oldObject != nil {
3821
+				return EventUpdateConfig{Config: v.Config, OldConfig: oldObject.(*Config)}, nil
3822
+			} else {
3823
+				return EventUpdateConfig{Config: v.Config}, nil
3824
+			}
3825
+		case StoreActionKindRemove:
3826
+			return EventDeleteConfig{Config: v.Config}, nil
3827
+		}
3815 3828
 	case *StoreAction_Resource:
3816 3829
 		switch sa.Action {
3817 3830
 		case StoreActionKindCreate:
... ...
@@ -3904,6 +4227,16 @@ func WatchMessageEvent(c Event) *WatchMessage_Event {
3904 3904
 		}
3905 3905
 	case EventDeleteSecret:
3906 3906
 		return &WatchMessage_Event{Action: WatchActionKindRemove, Object: &Object{Object: &Object_Secret{Secret: v.Secret}}}
3907
+	case EventCreateConfig:
3908
+		return &WatchMessage_Event{Action: WatchActionKindCreate, Object: &Object{Object: &Object_Config{Config: v.Config}}}
3909
+	case EventUpdateConfig:
3910
+		if v.OldConfig != nil {
3911
+			return &WatchMessage_Event{Action: WatchActionKindUpdate, Object: &Object{Object: &Object_Config{Config: v.Config}}, OldObject: &Object{Object: &Object_Config{Config: v.OldConfig}}}
3912
+		} else {
3913
+			return &WatchMessage_Event{Action: WatchActionKindUpdate, Object: &Object{Object: &Object_Config{Config: v.Config}}}
3914
+		}
3915
+	case EventDeleteConfig:
3916
+		return &WatchMessage_Event{Action: WatchActionKindRemove, Object: &Object{Object: &Object_Config{Config: v.Config}}}
3907 3917
 	case EventCreateResource:
3908 3918
 		return &WatchMessage_Event{Action: WatchActionKindCreate, Object: &Object{Object: &Object_Resource{Resource: v.Resource}}}
3909 3919
 	case EventUpdateResource:
... ...
@@ -3948,6 +4281,8 @@ func ConvertWatchArgs(entries []*WatchRequest_WatchEntry) ([]Event, error) {
3948 3948
 			newEvents, err = ConvertClusterWatch(entry.Action, entry.Filters)
3949 3949
 		case "secret":
3950 3950
 			newEvents, err = ConvertSecretWatch(entry.Action, entry.Filters)
3951
+		case "config":
3952
+			newEvents, err = ConvertConfigWatch(entry.Action, entry.Filters)
3951 3953
 		default:
3952 3954
 			newEvents, err = ConvertResourceWatch(entry.Action, entry.Filters, entry.Kind)
3953 3955
 		case "extension":
... ...
@@ -4120,6 +4455,18 @@ func (this *Secret) String() string {
4120 4120
 	}, "")
4121 4121
 	return s
4122 4122
 }
4123
+func (this *Config) String() string {
4124
+	if this == nil {
4125
+		return "nil"
4126
+	}
4127
+	s := strings.Join([]string{`&Config{`,
4128
+		`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
4129
+		`Meta:` + strings.Replace(strings.Replace(this.Meta.String(), "Meta", "Meta", 1), `&`, ``, 1) + `,`,
4130
+		`Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ConfigSpec", "ConfigSpec", 1), `&`, ``, 1) + `,`,
4131
+		`}`,
4132
+	}, "")
4133
+	return s
4134
+}
4123 4135
 func (this *Resource) String() string {
4124 4136
 	if this == nil {
4125 4137
 		return "nil"
... ...
@@ -6506,6 +6853,145 @@ func (m *Secret) Unmarshal(dAtA []byte) error {
6506 6506
 	}
6507 6507
 	return nil
6508 6508
 }
6509
+func (m *Config) Unmarshal(dAtA []byte) error {
6510
+	l := len(dAtA)
6511
+	iNdEx := 0
6512
+	for iNdEx < l {
6513
+		preIndex := iNdEx
6514
+		var wire uint64
6515
+		for shift := uint(0); ; shift += 7 {
6516
+			if shift >= 64 {
6517
+				return ErrIntOverflowObjects
6518
+			}
6519
+			if iNdEx >= l {
6520
+				return io.ErrUnexpectedEOF
6521
+			}
6522
+			b := dAtA[iNdEx]
6523
+			iNdEx++
6524
+			wire |= (uint64(b) & 0x7F) << shift
6525
+			if b < 0x80 {
6526
+				break
6527
+			}
6528
+		}
6529
+		fieldNum := int32(wire >> 3)
6530
+		wireType := int(wire & 0x7)
6531
+		if wireType == 4 {
6532
+			return fmt.Errorf("proto: Config: wiretype end group for non-group")
6533
+		}
6534
+		if fieldNum <= 0 {
6535
+			return fmt.Errorf("proto: Config: illegal tag %d (wire type %d)", fieldNum, wire)
6536
+		}
6537
+		switch fieldNum {
6538
+		case 1:
6539
+			if wireType != 2 {
6540
+				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
6541
+			}
6542
+			var stringLen uint64
6543
+			for shift := uint(0); ; shift += 7 {
6544
+				if shift >= 64 {
6545
+					return ErrIntOverflowObjects
6546
+				}
6547
+				if iNdEx >= l {
6548
+					return io.ErrUnexpectedEOF
6549
+				}
6550
+				b := dAtA[iNdEx]
6551
+				iNdEx++
6552
+				stringLen |= (uint64(b) & 0x7F) << shift
6553
+				if b < 0x80 {
6554
+					break
6555
+				}
6556
+			}
6557
+			intStringLen := int(stringLen)
6558
+			if intStringLen < 0 {
6559
+				return ErrInvalidLengthObjects
6560
+			}
6561
+			postIndex := iNdEx + intStringLen
6562
+			if postIndex > l {
6563
+				return io.ErrUnexpectedEOF
6564
+			}
6565
+			m.ID = string(dAtA[iNdEx:postIndex])
6566
+			iNdEx = postIndex
6567
+		case 2:
6568
+			if wireType != 2 {
6569
+				return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType)
6570
+			}
6571
+			var msglen int
6572
+			for shift := uint(0); ; shift += 7 {
6573
+				if shift >= 64 {
6574
+					return ErrIntOverflowObjects
6575
+				}
6576
+				if iNdEx >= l {
6577
+					return io.ErrUnexpectedEOF
6578
+				}
6579
+				b := dAtA[iNdEx]
6580
+				iNdEx++
6581
+				msglen |= (int(b) & 0x7F) << shift
6582
+				if b < 0x80 {
6583
+					break
6584
+				}
6585
+			}
6586
+			if msglen < 0 {
6587
+				return ErrInvalidLengthObjects
6588
+			}
6589
+			postIndex := iNdEx + msglen
6590
+			if postIndex > l {
6591
+				return io.ErrUnexpectedEOF
6592
+			}
6593
+			if err := m.Meta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
6594
+				return err
6595
+			}
6596
+			iNdEx = postIndex
6597
+		case 3:
6598
+			if wireType != 2 {
6599
+				return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
6600
+			}
6601
+			var msglen int
6602
+			for shift := uint(0); ; shift += 7 {
6603
+				if shift >= 64 {
6604
+					return ErrIntOverflowObjects
6605
+				}
6606
+				if iNdEx >= l {
6607
+					return io.ErrUnexpectedEOF
6608
+				}
6609
+				b := dAtA[iNdEx]
6610
+				iNdEx++
6611
+				msglen |= (int(b) & 0x7F) << shift
6612
+				if b < 0x80 {
6613
+					break
6614
+				}
6615
+			}
6616
+			if msglen < 0 {
6617
+				return ErrInvalidLengthObjects
6618
+			}
6619
+			postIndex := iNdEx + msglen
6620
+			if postIndex > l {
6621
+				return io.ErrUnexpectedEOF
6622
+			}
6623
+			if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
6624
+				return err
6625
+			}
6626
+			iNdEx = postIndex
6627
+		default:
6628
+			iNdEx = preIndex
6629
+			skippy, err := skipObjects(dAtA[iNdEx:])
6630
+			if err != nil {
6631
+				return err
6632
+			}
6633
+			if skippy < 0 {
6634
+				return ErrInvalidLengthObjects
6635
+			}
6636
+			if (iNdEx + skippy) > l {
6637
+				return io.ErrUnexpectedEOF
6638
+			}
6639
+			iNdEx += skippy
6640
+		}
6641
+	}
6642
+
6643
+	if iNdEx > l {
6644
+		return io.ErrUnexpectedEOF
6645
+	}
6646
+	return nil
6647
+}
6509 6648
 func (m *Resource) Unmarshal(dAtA []byte) error {
6510 6649
 	l := len(dAtA)
6511 6650
 	iNdEx := 0
... ...
@@ -6983,92 +7469,93 @@ var (
6983 6983
 func init() { proto.RegisterFile("objects.proto", fileDescriptorObjects) }
6984 6984
 
6985 6985
 var fileDescriptorObjects = []byte{
6986
-	// 1390 bytes of a gzipped FileDescriptorProto
6986
+	// 1405 bytes of a gzipped FileDescriptorProto
6987 6987
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x57, 0xc1, 0x6f, 0x1b, 0x45,
6988
-	0x17, 0xef, 0xda, 0x1b, 0xdb, 0xfb, 0x9c, 0x58, 0xf9, 0xa6, 0xf9, 0xf2, 0x6d, 0xf3, 0xe5, 0xb3,
6989
-	0xf3, 0xb9, 0x02, 0x55, 0xa8, 0x72, 0x4a, 0x29, 0x28, 0x0d, 0x14, 0x6a, 0x27, 0x16, 0xb5, 0x4a,
6990
-	0x69, 0x34, 0x2d, 0x2d, 0x37, 0x33, 0xd9, 0x9d, 0xba, 0x8b, 0xd7, 0x3b, 0xab, 0x9d, 0xb1, 0x8b,
6991
-	0x6f, 0x88, 0x63, 0xfe, 0x81, 0xdc, 0x38, 0x70, 0xe2, 0x0e, 0x17, 0x2e, 0x9c, 0x7b, 0xe4, 0x84,
6992
-	0x38, 0x45, 0xd4, 0xff, 0x05, 0x12, 0x07, 0x34, 0xb3, 0xb3, 0xce, 0xa6, 0x5e, 0x27, 0x2d, 0xaa,
6993
-	0x2a, 0x4e, 0x9e, 0xd9, 0xf9, 0xfd, 0xde, 0xbc, 0xf7, 0xe6, 0x37, 0x6f, 0x9e, 0x61, 0x89, 0xed,
6994
-	0x7f, 0x49, 0x1d, 0xc1, 0x1b, 0x61, 0xc4, 0x04, 0x43, 0xc8, 0x65, 0x4e, 0x9f, 0x46, 0x0d, 0xfe,
6995
-	0x84, 0x44, 0x83, 0xbe, 0x27, 0x1a, 0xa3, 0xb7, 0xd7, 0xca, 0x62, 0x1c, 0x52, 0x0d, 0x58, 0x2b,
6996
-	0xf3, 0x90, 0x3a, 0xc9, 0xa4, 0xd6, 0x63, 0xac, 0xe7, 0xd3, 0x4d, 0x35, 0xdb, 0x1f, 0x3e, 0xda,
6997
-	0x14, 0xde, 0x80, 0x72, 0x41, 0x06, 0xa1, 0x06, 0xac, 0xf4, 0x58, 0x8f, 0xa9, 0xe1, 0xa6, 0x1c,
6998
-	0xe9, 0xaf, 0x17, 0x9e, 0xa7, 0x91, 0x60, 0xac, 0x97, 0xce, 0x87, 0xfe, 0xb0, 0xe7, 0x05, 0x9b,
6999
-	0xf1, 0x4f, 0xfc, 0xb1, 0xfe, 0x93, 0x01, 0xe6, 0x1d, 0x2a, 0x08, 0x7a, 0x1f, 0x8a, 0x23, 0x1a,
7000
-	0x71, 0x8f, 0x05, 0xb6, 0xb1, 0x61, 0x5c, 0x2a, 0x5f, 0xfd, 0x6f, 0x63, 0xd6, 0xdf, 0xc6, 0x83,
7001
-	0x18, 0xd2, 0x32, 0x9f, 0x1e, 0xd5, 0xce, 0xe1, 0x84, 0x81, 0xae, 0x03, 0x38, 0x11, 0x25, 0x82,
7002
-	0xba, 0x5d, 0x22, 0xec, 0x9c, 0xe2, 0xaf, 0x35, 0x62, 0x57, 0x1a, 0x89, 0x2b, 0x8d, 0xfb, 0x49,
7003
-	0x04, 0xd8, 0xd2, 0xe8, 0xa6, 0x90, 0xd4, 0x61, 0xe8, 0x26, 0xd4, 0xfc, 0xd9, 0x54, 0x8d, 0x6e,
7004
-	0x8a, 0xfa, 0x0f, 0x26, 0x98, 0x9f, 0x32, 0x97, 0xa2, 0x55, 0xc8, 0x79, 0xae, 0x72, 0xdb, 0x6a,
7005
-	0x15, 0x26, 0x47, 0xb5, 0x5c, 0x67, 0x17, 0xe7, 0x3c, 0x17, 0x5d, 0x05, 0x73, 0x40, 0x05, 0xd1,
7006
-	0x0e, 0xd9, 0x59, 0x01, 0xc9, 0xd8, 0x75, 0x34, 0x0a, 0x8b, 0xde, 0x03, 0x53, 0x1e, 0x83, 0xf6,
7007
-	0x64, 0x3d, 0x8b, 0x23, 0xf7, 0xbc, 0x17, 0x52, 0x27, 0xe1, 0x49, 0x3c, 0x6a, 0x43, 0xd9, 0xa5,
7008
-	0xdc, 0x89, 0xbc, 0x50, 0xc8, 0x1c, 0x9a, 0x8a, 0x7e, 0x71, 0x1e, 0x7d, 0xf7, 0x18, 0x8a, 0xd3,
7009
-	0x3c, 0xf4, 0x01, 0x14, 0xb8, 0x20, 0x62, 0xc8, 0xed, 0x05, 0x65, 0xa1, 0x3a, 0xd7, 0x01, 0x85,
7010
-	0xd2, 0x2e, 0x68, 0x0e, 0xba, 0x05, 0x95, 0x01, 0x09, 0x48, 0x8f, 0x46, 0x5d, 0x6d, 0xa5, 0xa0,
7011
-	0xac, 0xfc, 0x3f, 0x33, 0xf4, 0x18, 0x19, 0x1b, 0xc2, 0x4b, 0x83, 0xf4, 0x14, 0xb5, 0x01, 0x88,
7012
-	0x10, 0xc4, 0x79, 0x3c, 0xa0, 0x81, 0xb0, 0x8b, 0xca, 0xca, 0x1b, 0x99, 0xbe, 0x50, 0xf1, 0x84,
7013
-	0x45, 0xfd, 0xe6, 0x14, 0x8c, 0x53, 0x44, 0xf4, 0x31, 0x94, 0x1d, 0x1a, 0x09, 0xef, 0x91, 0xe7,
7014
-	0x10, 0x41, 0xed, 0x92, 0xb2, 0x53, 0xcb, 0xb2, 0xb3, 0x73, 0x0c, 0xd3, 0x41, 0xa5, 0x99, 0xe8,
7015
-	0x0a, 0x98, 0x11, 0xf3, 0xa9, 0x6d, 0x6d, 0x18, 0x97, 0x2a, 0xf3, 0x8f, 0x05, 0x33, 0x9f, 0x62,
7016
-	0x85, 0xdc, 0x5e, 0x3d, 0x38, 0xac, 0x23, 0x58, 0x2e, 0x19, 0xcb, 0x86, 0x92, 0x86, 0x71, 0xc5,
7017
-	0xf8, 0xdc, 0xf8, 0xc2, 0xa8, 0xff, 0x99, 0x87, 0xe2, 0x3d, 0x1a, 0x8d, 0x3c, 0xe7, 0xd5, 0x0a,
7018
-	0xe7, 0xfa, 0x09, 0xe1, 0x64, 0xc6, 0xa8, 0xb7, 0x9d, 0xd1, 0xce, 0x16, 0x94, 0x68, 0xe0, 0x86,
7019
-	0xcc, 0x0b, 0x84, 0x16, 0x4e, 0x66, 0x80, 0x6d, 0x8d, 0xc1, 0x53, 0x34, 0x6a, 0xc3, 0x52, 0x7c,
7020
-	0x1f, 0xba, 0x27, 0x54, 0xb3, 0x91, 0x45, 0xff, 0x4c, 0x01, 0xf5, 0x71, 0x2f, 0x0e, 0x53, 0x33,
7021
-	0xb4, 0x0b, 0x4b, 0x61, 0x44, 0x47, 0x1e, 0x1b, 0xf2, 0xae, 0x0a, 0xa2, 0xf0, 0x42, 0x41, 0xe0,
7022
-	0xc5, 0x84, 0x25, 0x67, 0xe8, 0x43, 0x58, 0x94, 0xe4, 0x6e, 0x52, 0x47, 0xe0, 0xcc, 0x3a, 0x82,
7023
-	0x55, 0xc9, 0xd3, 0x13, 0x74, 0x17, 0xfe, 0x7d, 0xc2, 0x8b, 0xa9, 0xa1, 0xf2, 0xd9, 0x86, 0xce,
7024
-	0xa7, 0x3d, 0xd1, 0x1f, 0xb7, 0xd1, 0xc1, 0x61, 0xbd, 0x02, 0x8b, 0x69, 0x09, 0xd4, 0xbf, 0xcd,
7025
-	0x41, 0x29, 0x49, 0x24, 0xba, 0xa6, 0xcf, 0xcc, 0x98, 0x9f, 0xb5, 0x04, 0xab, 0xe2, 0x8d, 0x8f,
7026
-	0xeb, 0x1a, 0x2c, 0x84, 0x2c, 0x12, 0xdc, 0xce, 0x6d, 0xe4, 0xe7, 0x5d, 0xd1, 0x3d, 0x16, 0x89,
7027
-	0x1d, 0x16, 0x3c, 0xf2, 0x7a, 0x38, 0x06, 0xa3, 0x87, 0x50, 0x1e, 0x79, 0x91, 0x18, 0x12, 0xbf,
7028
-	0xeb, 0x85, 0xdc, 0xce, 0x2b, 0xee, 0x9b, 0xa7, 0x6d, 0xd9, 0x78, 0x10, 0xe3, 0x3b, 0x7b, 0xad,
7029
-	0xca, 0xe4, 0xa8, 0x06, 0xd3, 0x29, 0xc7, 0xa0, 0x4d, 0x75, 0x42, 0xbe, 0x76, 0x07, 0xac, 0xe9,
7030
-	0x0a, 0xba, 0x0c, 0x10, 0xc4, 0x37, 0xb2, 0x3b, 0x55, 0xf6, 0xd2, 0xe4, 0xa8, 0x66, 0xe9, 0x7b,
7031
-	0xda, 0xd9, 0xc5, 0x96, 0x06, 0x74, 0x5c, 0x84, 0xc0, 0x24, 0xae, 0x1b, 0x29, 0x9d, 0x5b, 0x58,
7032
-	0x8d, 0xeb, 0xdf, 0x17, 0xc0, 0xbc, 0x4f, 0x78, 0xff, 0x75, 0x57, 0x55, 0xb9, 0xe7, 0xcc, 0xcd,
7033
-	0xb8, 0x0c, 0xc0, 0x63, 0xbd, 0xc9, 0x70, 0xcc, 0xe3, 0x70, 0xb4, 0x0a, 0x65, 0x38, 0x1a, 0x10,
7034
-	0x87, 0xc3, 0x7d, 0x26, 0xd4, 0x25, 0x30, 0xb1, 0x1a, 0xa3, 0x8b, 0x50, 0x0c, 0x98, 0xab, 0xe8,
7035
-	0x05, 0x45, 0x87, 0xc9, 0x51, 0xad, 0x20, 0x6b, 0x45, 0x67, 0x17, 0x17, 0xe4, 0x52, 0xc7, 0x95,
7036
-	0x65, 0x8a, 0x04, 0x01, 0x13, 0x44, 0xd6, 0x60, 0xae, 0xcb, 0x5d, 0xa6, 0xfa, 0x9b, 0xc7, 0xb0,
7037
-	0xa4, 0x4c, 0xa5, 0x98, 0xe8, 0x01, 0x9c, 0x4f, 0xfc, 0x4d, 0x1b, 0x2c, 0xbd, 0x8c, 0x41, 0xa4,
7038
-	0x2d, 0xa4, 0x56, 0x52, 0xcf, 0x82, 0x35, 0xff, 0x59, 0x50, 0x19, 0xcc, 0x7a, 0x16, 0x5a, 0xb0,
7039
-	0xe4, 0x52, 0xee, 0x45, 0xd4, 0x55, 0x65, 0x82, 0xaa, 0x9b, 0x59, 0xb9, 0xfa, 0xbf, 0xd3, 0x8c,
7040
-	0x50, 0xbc, 0xa8, 0x39, 0x6a, 0x86, 0x9a, 0x50, 0xd2, 0xba, 0xe1, 0x76, 0x59, 0x69, 0xf7, 0x05,
7041
-	0x9f, 0x83, 0x29, 0xed, 0x44, 0x99, 0x5b, 0x7c, 0xa9, 0x32, 0x77, 0x1d, 0xc0, 0x67, 0xbd, 0xae,
7042
-	0x1b, 0x79, 0x23, 0x1a, 0xd9, 0x4b, 0xba, 0x49, 0xc8, 0xe0, 0xee, 0x2a, 0x04, 0xb6, 0x7c, 0xd6,
7043
-	0x8b, 0x87, 0x33, 0x45, 0xa9, 0xf2, 0x72, 0x45, 0x69, 0x7b, 0xed, 0xe0, 0xb0, 0xbe, 0x0a, 0x2b,
7044
-	0xe9, 0x1a, 0xb2, 0x65, 0xdc, 0x34, 0x6e, 0x19, 0x7b, 0x46, 0xfd, 0x1b, 0x03, 0xfe, 0x35, 0x13,
7045
-	0x30, 0x7a, 0x17, 0x8a, 0x3a, 0xe4, 0xd3, 0x3a, 0x29, 0xcd, 0xc3, 0x09, 0x16, 0xad, 0x83, 0x25,
7046
-	0xef, 0x1f, 0xe5, 0x9c, 0xc6, 0x95, 0xc5, 0xc2, 0xc7, 0x1f, 0x90, 0x0d, 0x45, 0xe2, 0x7b, 0x44,
7047
-	0xae, 0xe5, 0xd5, 0x5a, 0x32, 0xad, 0x7f, 0x97, 0x83, 0xa2, 0x36, 0xf6, 0xba, 0xdf, 0x33, 0xbd,
7048
-	0xed, 0xcc, 0xad, 0xbd, 0x01, 0x8b, 0xf1, 0x51, 0x69, 0xb9, 0x99, 0x67, 0x1e, 0x58, 0x39, 0xc6,
7049
-	0xc7, 0x52, 0xbb, 0x01, 0xa6, 0x17, 0x92, 0x81, 0x7e, 0xcb, 0x32, 0x77, 0xee, 0xec, 0x35, 0xef,
7050
-	0xdc, 0x0d, 0xe3, 0x5b, 0x53, 0x9a, 0x1c, 0xd5, 0x4c, 0xf9, 0x01, 0x2b, 0x5a, 0x66, 0xd5, 0xff,
7051
-	0x71, 0x01, 0x8a, 0x3b, 0xfe, 0x90, 0x0b, 0x1a, 0xbd, 0xee, 0x24, 0xe9, 0x6d, 0x67, 0x92, 0xb4,
7052
-	0x03, 0xc5, 0x88, 0x31, 0xd1, 0x75, 0xc8, 0x69, 0xf9, 0xc1, 0x8c, 0x89, 0x9d, 0x66, 0xab, 0x22,
7053
-	0x89, 0xb2, 0x70, 0xc5, 0x73, 0x5c, 0x90, 0xd4, 0x1d, 0x82, 0x1e, 0xc2, 0x6a, 0x52, 0xee, 0xf7,
7054
-	0x19, 0x13, 0x5c, 0x44, 0x24, 0xec, 0xf6, 0xe9, 0x58, 0x36, 0x02, 0xf9, 0x79, 0x8d, 0x5f, 0x3b,
7055
-	0x70, 0xa2, 0xb1, 0x4a, 0xde, 0x6d, 0x3a, 0xc6, 0x2b, 0xda, 0x40, 0x2b, 0xe1, 0xdf, 0xa6, 0x63,
7056
-	0x8e, 0x3e, 0x82, 0x75, 0x3a, 0x85, 0x49, 0x8b, 0x5d, 0x9f, 0x0c, 0xe4, 0x43, 0xd6, 0x75, 0x7c,
7057
-	0xe6, 0xf4, 0x55, 0x2d, 0x35, 0xf1, 0x05, 0x9a, 0x36, 0xf5, 0x49, 0x8c, 0xd8, 0x91, 0x00, 0xc4,
7058
-	0xc1, 0xde, 0xf7, 0x89, 0xd3, 0xf7, 0x3d, 0x2e, 0x7b, 0xfb, 0x54, 0x2f, 0x27, 0xcb, 0xa1, 0xf4,
7059
-	0x6d, 0xeb, 0x94, 0x6c, 0x35, 0x5a, 0xc7, 0xdc, 0x54, 0x67, 0xc8, 0xdb, 0x81, 0x88, 0xc6, 0xf8,
7060
-	0x3f, 0xfb, 0xd9, 0xab, 0xa8, 0x05, 0xe5, 0x61, 0x20, 0xb7, 0x8f, 0x73, 0x60, 0xbd, 0x68, 0x0e,
7061
-	0x20, 0x66, 0xc9, 0xc8, 0xd7, 0x46, 0xb0, 0x7e, 0xda, 0xe6, 0x68, 0x19, 0xf2, 0x7d, 0x3a, 0x8e,
7062
-	0xf5, 0x83, 0xe5, 0x10, 0xdd, 0x84, 0x85, 0x11, 0xf1, 0x87, 0x54, 0x2b, 0xe7, 0xad, 0xac, 0xfd,
7063
-	0xb2, 0x4d, 0xe2, 0x98, 0xb8, 0x9d, 0xdb, 0x32, 0x32, 0x65, 0xfb, 0xb3, 0x01, 0x85, 0x7b, 0xd4,
7064
-	0x89, 0xa8, 0x78, 0xa5, 0xaa, 0xdd, 0x3a, 0xa1, 0xda, 0x6a, 0x76, 0x97, 0x27, 0x77, 0x9d, 0x11,
7065
-	0xed, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0x52, 0x6d, 0x09, 0x4f, 0xe7, 0x99, 0x01,
7066
-	0xfc, 0x61, 0x40, 0x09, 0x53, 0xce, 0x86, 0xd1, 0x2b, 0xee, 0xb6, 0x9f, 0x7b, 0xb1, 0xf3, 0x7f,
7067
-	0xfb, 0xc5, 0x46, 0x60, 0xf6, 0xbd, 0x40, 0xf7, 0x16, 0x58, 0x8d, 0x51, 0x03, 0x8a, 0x21, 0x19,
7068
-	0xfb, 0x8c, 0xb8, 0xba, 0x06, 0xad, 0xcc, 0xfc, 0x21, 0x6d, 0x06, 0x63, 0x9c, 0x80, 0xb6, 0x57,
7069
-	0x0e, 0x0e, 0xeb, 0xcb, 0x50, 0x49, 0x47, 0xfe, 0xd8, 0xa8, 0xff, 0x6a, 0x80, 0xd5, 0xfe, 0x4a,
7070
-	0xd0, 0x40, 0x35, 0xb7, 0xff, 0xc8, 0xe0, 0x37, 0x66, 0xff, 0xb4, 0x5a, 0x27, 0xfe, 0x8f, 0x66,
7071
-	0x1d, 0x6a, 0xcb, 0x7e, 0xfa, 0xac, 0x7a, 0xee, 0xb7, 0x67, 0xd5, 0x73, 0x5f, 0x4f, 0xaa, 0xc6,
7072
-	0xd3, 0x49, 0xd5, 0xf8, 0x65, 0x52, 0x35, 0x7e, 0x9f, 0x54, 0x8d, 0xfd, 0x82, 0xca, 0xcf, 0x3b,
7073
-	0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x01, 0x4f, 0xd2, 0x2a, 0xfa, 0x10, 0x00, 0x00,
6988
+	0x17, 0xef, 0xda, 0x1b, 0xdb, 0xfb, 0x9c, 0x58, 0xf9, 0xa6, 0xf9, 0xf2, 0x6d, 0xf3, 0x05, 0x3b,
6989
+	0xb8, 0x02, 0x55, 0xa8, 0x72, 0x4a, 0x29, 0x28, 0x0d, 0x14, 0x6a, 0x27, 0x11, 0xb5, 0x4a, 0x69,
6990
+	0x34, 0x2d, 0x2d, 0x37, 0x33, 0xd9, 0x9d, 0xba, 0x8b, 0xd7, 0x3b, 0xab, 0x9d, 0xb1, 0x8b, 0x6f,
6991
+	0x88, 0x63, 0xfe, 0x81, 0xdc, 0x38, 0xf4, 0xc4, 0x1d, 0x2e, 0x5c, 0x38, 0xf7, 0xc8, 0x09, 0x71,
6992
+	0x8a, 0xa8, 0xff, 0x0b, 0x24, 0x0e, 0x68, 0x66, 0x67, 0x9d, 0x4d, 0xbd, 0x4e, 0x5a, 0x54, 0x45,
6993
+	0x9c, 0x3c, 0xb3, 0xf3, 0xfb, 0xbd, 0x79, 0xef, 0xcd, 0x6f, 0xde, 0x3c, 0xc3, 0x02, 0xdb, 0xfb,
6994
+	0x9a, 0x3a, 0x82, 0x37, 0xc2, 0x88, 0x09, 0x86, 0x90, 0xcb, 0x9c, 0x1e, 0x8d, 0x1a, 0xfc, 0x09,
6995
+	0x89, 0xfa, 0x3d, 0x4f, 0x34, 0x86, 0xef, 0xae, 0x94, 0xc5, 0x28, 0xa4, 0x1a, 0xb0, 0x52, 0xe6,
6996
+	0x21, 0x75, 0x92, 0x49, 0xad, 0xcb, 0x58, 0xd7, 0xa7, 0xeb, 0x6a, 0xb6, 0x37, 0x78, 0xb4, 0x2e,
6997
+	0xbc, 0x3e, 0xe5, 0x82, 0xf4, 0x43, 0x0d, 0x58, 0xea, 0xb2, 0x2e, 0x53, 0xc3, 0x75, 0x39, 0xd2,
6998
+	0x5f, 0x2f, 0xbc, 0x48, 0x23, 0xc1, 0x48, 0x2f, 0x9d, 0x0f, 0xfd, 0x41, 0xd7, 0x0b, 0xd6, 0xe3,
6999
+	0x9f, 0xf8, 0x63, 0xfd, 0x67, 0x03, 0xcc, 0x3b, 0x54, 0x10, 0xf4, 0x21, 0x14, 0x87, 0x34, 0xe2,
7000
+	0x1e, 0x0b, 0x6c, 0x63, 0xcd, 0xb8, 0x54, 0xbe, 0xfa, 0xff, 0xc6, 0xb4, 0xbf, 0x8d, 0x07, 0x31,
7001
+	0xa4, 0x65, 0x3e, 0x3b, 0xac, 0x9d, 0xc3, 0x09, 0x03, 0x5d, 0x07, 0x70, 0x22, 0x4a, 0x04, 0x75,
7002
+	0x3b, 0x44, 0xd8, 0x39, 0xc5, 0x5f, 0x69, 0xc4, 0xae, 0x34, 0x12, 0x57, 0x1a, 0xf7, 0x93, 0x08,
7003
+	0xb0, 0xa5, 0xd1, 0x4d, 0x21, 0xa9, 0x83, 0xd0, 0x4d, 0xa8, 0xf9, 0xd3, 0xa9, 0x1a, 0xdd, 0x14,
7004
+	0xf5, 0x1f, 0x4d, 0x30, 0x3f, 0x67, 0x2e, 0x45, 0xcb, 0x90, 0xf3, 0x5c, 0xe5, 0xb6, 0xd5, 0x2a,
7005
+	0x8c, 0x0f, 0x6b, 0xb9, 0xf6, 0x36, 0xce, 0x79, 0x2e, 0xba, 0x0a, 0x66, 0x9f, 0x0a, 0xa2, 0x1d,
7006
+	0xb2, 0xb3, 0x02, 0x92, 0xb1, 0xeb, 0x68, 0x14, 0x16, 0x7d, 0x00, 0xa6, 0x3c, 0x06, 0xed, 0xc9,
7007
+	0x6a, 0x16, 0x47, 0xee, 0x79, 0x2f, 0xa4, 0x4e, 0xc2, 0x93, 0x78, 0xb4, 0x03, 0x65, 0x97, 0x72,
7008
+	0x27, 0xf2, 0x42, 0x21, 0x73, 0x68, 0x2a, 0xfa, 0xc5, 0x59, 0xf4, 0xed, 0x23, 0x28, 0x4e, 0xf3,
7009
+	0xd0, 0x47, 0x50, 0xe0, 0x82, 0x88, 0x01, 0xb7, 0xe7, 0x94, 0x85, 0xea, 0x4c, 0x07, 0x14, 0x4a,
7010
+	0xbb, 0xa0, 0x39, 0xe8, 0x16, 0x54, 0xfa, 0x24, 0x20, 0x5d, 0x1a, 0x75, 0xb4, 0x95, 0x82, 0xb2,
7011
+	0xf2, 0x66, 0x66, 0xe8, 0x31, 0x32, 0x36, 0x84, 0x17, 0xfa, 0xe9, 0x29, 0xda, 0x01, 0x20, 0x42,
7012
+	0x10, 0xe7, 0x71, 0x9f, 0x06, 0xc2, 0x2e, 0x2a, 0x2b, 0x6f, 0x65, 0xfa, 0x42, 0xc5, 0x13, 0x16,
7013
+	0xf5, 0x9a, 0x13, 0x30, 0x4e, 0x11, 0xd1, 0xa7, 0x50, 0x76, 0x68, 0x24, 0xbc, 0x47, 0x9e, 0x43,
7014
+	0x04, 0xb5, 0x4b, 0xca, 0x4e, 0x2d, 0xcb, 0xce, 0xd6, 0x11, 0x4c, 0x07, 0x95, 0x66, 0xa2, 0x2b,
7015
+	0x60, 0x46, 0xcc, 0xa7, 0xb6, 0xb5, 0x66, 0x5c, 0xaa, 0xcc, 0x3e, 0x16, 0xcc, 0x7c, 0x8a, 0x15,
7016
+	0x72, 0x73, 0x79, 0xff, 0xa0, 0x8e, 0x60, 0xb1, 0x64, 0x2c, 0x1a, 0x4a, 0x1a, 0xc6, 0x15, 0xe3,
7017
+	0x4b, 0xe3, 0x2b, 0xa3, 0xfe, 0x57, 0x1e, 0x8a, 0xf7, 0x68, 0x34, 0xf4, 0x9c, 0xd7, 0x2b, 0x9c,
7018
+	0xeb, 0xc7, 0x84, 0x93, 0x19, 0xa3, 0xde, 0x76, 0x4a, 0x3b, 0x1b, 0x50, 0xa2, 0x81, 0x1b, 0x32,
7019
+	0x2f, 0x10, 0x5a, 0x38, 0x99, 0x01, 0xee, 0x68, 0x0c, 0x9e, 0xa0, 0xd1, 0x0e, 0x2c, 0xc4, 0xf7,
7020
+	0xa1, 0x73, 0x4c, 0x35, 0x6b, 0x59, 0xf4, 0x2f, 0x14, 0x50, 0x1f, 0xf7, 0xfc, 0x20, 0x35, 0x43,
7021
+	0xdb, 0xb0, 0x10, 0x46, 0x74, 0xe8, 0xb1, 0x01, 0xef, 0xa8, 0x20, 0x0a, 0x2f, 0x15, 0x04, 0x9e,
7022
+	0x4f, 0x58, 0x72, 0x86, 0x3e, 0x86, 0x79, 0x49, 0xee, 0x24, 0x75, 0x04, 0x4e, 0xad, 0x23, 0x58,
7023
+	0x95, 0x3c, 0x3d, 0x41, 0x77, 0xe1, 0xbf, 0xc7, 0xbc, 0x98, 0x18, 0x2a, 0x9f, 0x6e, 0xe8, 0x7c,
7024
+	0xda, 0x13, 0xfd, 0x71, 0x13, 0xed, 0x1f, 0xd4, 0x2b, 0x30, 0x9f, 0x96, 0x40, 0xfd, 0xfb, 0x1c,
7025
+	0x94, 0x92, 0x44, 0xa2, 0x6b, 0xfa, 0xcc, 0x8c, 0xd9, 0x59, 0x4b, 0xb0, 0x2a, 0xde, 0xf8, 0xb8,
7026
+	0xae, 0xc1, 0x5c, 0xc8, 0x22, 0xc1, 0xed, 0xdc, 0x5a, 0x7e, 0xd6, 0x15, 0xdd, 0x65, 0x91, 0xd8,
7027
+	0x62, 0xc1, 0x23, 0xaf, 0x8b, 0x63, 0x30, 0x7a, 0x08, 0xe5, 0xa1, 0x17, 0x89, 0x01, 0xf1, 0x3b,
7028
+	0x5e, 0xc8, 0xed, 0xbc, 0xe2, 0xbe, 0x7d, 0xd2, 0x96, 0x8d, 0x07, 0x31, 0xbe, 0xbd, 0xdb, 0xaa,
7029
+	0x8c, 0x0f, 0x6b, 0x30, 0x99, 0x72, 0x0c, 0xda, 0x54, 0x3b, 0xe4, 0x2b, 0x77, 0xc0, 0x9a, 0xac,
7030
+	0xa0, 0xcb, 0x00, 0x41, 0x7c, 0x23, 0x3b, 0x13, 0x65, 0x2f, 0x8c, 0x0f, 0x6b, 0x96, 0xbe, 0xa7,
7031
+	0xed, 0x6d, 0x6c, 0x69, 0x40, 0xdb, 0x45, 0x08, 0x4c, 0xe2, 0xba, 0x91, 0xd2, 0xb9, 0x85, 0xd5,
7032
+	0xb8, 0xfe, 0x43, 0x01, 0xcc, 0xfb, 0x84, 0xf7, 0xce, 0xba, 0xaa, 0xca, 0x3d, 0xa7, 0x6e, 0xc6,
7033
+	0x65, 0x00, 0x1e, 0xeb, 0x4d, 0x86, 0x63, 0x1e, 0x85, 0xa3, 0x55, 0x28, 0xc3, 0xd1, 0x80, 0x38,
7034
+	0x1c, 0xee, 0x33, 0xa1, 0x2e, 0x81, 0x89, 0xd5, 0x18, 0x5d, 0x84, 0x62, 0xc0, 0x5c, 0x45, 0x2f,
7035
+	0x28, 0x3a, 0x8c, 0x0f, 0x6b, 0x05, 0x59, 0x2b, 0xda, 0xdb, 0xb8, 0x20, 0x97, 0xda, 0xae, 0x2c,
7036
+	0x53, 0x24, 0x08, 0x98, 0x20, 0xb2, 0x06, 0x73, 0x5d, 0xee, 0x32, 0xd5, 0xdf, 0x3c, 0x82, 0x25,
7037
+	0x65, 0x2a, 0xc5, 0x44, 0x0f, 0xe0, 0x7c, 0xe2, 0x6f, 0xda, 0x60, 0xe9, 0x55, 0x0c, 0x22, 0x6d,
7038
+	0x21, 0xb5, 0x92, 0x7a, 0x16, 0xac, 0xd9, 0xcf, 0x82, 0xca, 0x60, 0xd6, 0xb3, 0xd0, 0x82, 0x05,
7039
+	0x97, 0x72, 0x2f, 0xa2, 0xae, 0x2a, 0x13, 0x54, 0xdd, 0xcc, 0xca, 0xd5, 0x37, 0x4e, 0x32, 0x42,
7040
+	0xf1, 0xbc, 0xe6, 0xa8, 0x19, 0x6a, 0x42, 0x49, 0xeb, 0x86, 0xdb, 0x65, 0xa5, 0xdd, 0x97, 0x7c,
7041
+	0x0e, 0x26, 0xb4, 0x63, 0x65, 0x6e, 0xfe, 0x95, 0xca, 0xdc, 0x75, 0x00, 0x9f, 0x75, 0x3b, 0x6e,
7042
+	0xe4, 0x0d, 0x69, 0x64, 0x2f, 0xe8, 0x26, 0x21, 0x83, 0xbb, 0xad, 0x10, 0xd8, 0xf2, 0x59, 0x37,
7043
+	0x1e, 0x4e, 0x15, 0xa5, 0xca, 0xab, 0x15, 0xa5, 0xcd, 0x95, 0xfd, 0x83, 0xfa, 0x32, 0x2c, 0xa5,
7044
+	0x6b, 0xc8, 0x86, 0x71, 0xd3, 0xb8, 0x65, 0xec, 0x1a, 0xf5, 0xef, 0x0c, 0xf8, 0xcf, 0x54, 0xc0,
7045
+	0xe8, 0x7d, 0x28, 0xea, 0x90, 0x4f, 0xea, 0xa4, 0x34, 0x0f, 0x27, 0x58, 0xb4, 0x0a, 0x96, 0xbc,
7046
+	0x7f, 0x94, 0x73, 0x1a, 0x57, 0x16, 0x0b, 0x1f, 0x7d, 0x40, 0x36, 0x14, 0x89, 0xef, 0x11, 0xb9,
7047
+	0x96, 0x57, 0x6b, 0xc9, 0xb4, 0xfe, 0x34, 0x07, 0x45, 0x6d, 0xec, 0xac, 0xdf, 0x33, 0xbd, 0xed,
7048
+	0xd4, 0xad, 0xbd, 0x01, 0xf3, 0xf1, 0x51, 0x69, 0xb9, 0x99, 0xa7, 0x1e, 0x58, 0x39, 0xc6, 0xc7,
7049
+	0x52, 0xbb, 0x01, 0xa6, 0x17, 0x92, 0xbe, 0x7e, 0xcb, 0x32, 0x77, 0x6e, 0xef, 0x36, 0xef, 0xdc,
7050
+	0x0d, 0xe3, 0x5b, 0x53, 0x1a, 0x1f, 0xd6, 0x4c, 0xf9, 0x01, 0x2b, 0x5a, 0x66, 0xd5, 0xff, 0x69,
7051
+	0x0e, 0x8a, 0x5b, 0xfe, 0x80, 0x0b, 0x1a, 0x9d, 0x75, 0x92, 0xf4, 0xb6, 0x53, 0x49, 0xda, 0x82,
7052
+	0x62, 0xc4, 0x98, 0xe8, 0x38, 0xe4, 0xa4, 0xfc, 0x60, 0xc6, 0xc4, 0x56, 0xb3, 0x55, 0x91, 0x44,
7053
+	0x59, 0xb8, 0xe2, 0x39, 0x2e, 0x48, 0xea, 0x16, 0x41, 0x0f, 0x61, 0x39, 0x29, 0xf7, 0x7b, 0x8c,
7054
+	0x09, 0x2e, 0x22, 0x12, 0x76, 0x7a, 0x74, 0x24, 0x1b, 0x81, 0xfc, 0xac, 0xc6, 0x6f, 0x27, 0x70,
7055
+	0xa2, 0x91, 0x4a, 0xde, 0x6d, 0x3a, 0xc2, 0x4b, 0xda, 0x40, 0x2b, 0xe1, 0xdf, 0xa6, 0x23, 0x8e,
7056
+	0x3e, 0x81, 0x55, 0x3a, 0x81, 0x49, 0x8b, 0x1d, 0x9f, 0xf4, 0xe5, 0x43, 0xd6, 0x71, 0x7c, 0xe6,
7057
+	0xf4, 0x54, 0x2d, 0x35, 0xf1, 0x05, 0x9a, 0x36, 0xf5, 0x59, 0x8c, 0xd8, 0x92, 0x00, 0xc4, 0xc1,
7058
+	0xde, 0xf3, 0x89, 0xd3, 0xf3, 0x3d, 0x2e, 0x7b, 0xfb, 0x54, 0x2f, 0x27, 0xcb, 0xa1, 0xf4, 0x6d,
7059
+	0xe3, 0x84, 0x6c, 0x35, 0x5a, 0x47, 0xdc, 0x54, 0x67, 0xc8, 0x77, 0x02, 0x11, 0x8d, 0xf0, 0xff,
7060
+	0xf6, 0xb2, 0x57, 0x51, 0x0b, 0xca, 0x83, 0x40, 0x6e, 0x1f, 0xe7, 0xc0, 0x7a, 0xd9, 0x1c, 0x40,
7061
+	0xcc, 0x92, 0x91, 0xaf, 0x0c, 0x61, 0xf5, 0xa4, 0xcd, 0xd1, 0x22, 0xe4, 0x7b, 0x74, 0x14, 0xeb,
7062
+	0x07, 0xcb, 0x21, 0xba, 0x09, 0x73, 0x43, 0xe2, 0x0f, 0xa8, 0x56, 0xce, 0x3b, 0x59, 0xfb, 0x65,
7063
+	0x9b, 0xc4, 0x31, 0x71, 0x33, 0xb7, 0x61, 0x64, 0xca, 0xf6, 0x17, 0x03, 0x0a, 0xf7, 0xa8, 0x13,
7064
+	0x51, 0xf1, 0x5a, 0x55, 0xbb, 0x71, 0x4c, 0xb5, 0xd5, 0xec, 0x2e, 0x4f, 0xee, 0x3a, 0x25, 0xda,
7065
+	0x15, 0x28, 0x79, 0x81, 0xa0, 0x51, 0x40, 0x7c, 0xa5, 0xda, 0x12, 0x9e, 0xcc, 0x33, 0x03, 0x78,
7066
+	0x6a, 0x40, 0x21, 0x6e, 0x83, 0xce, 0x3a, 0x80, 0x78, 0xd7, 0x17, 0x03, 0xc8, 0x74, 0xf2, 0x4f,
7067
+	0x03, 0x4a, 0x98, 0x72, 0x36, 0x88, 0x5e, 0xf3, 0x5f, 0x82, 0x17, 0xda, 0x8a, 0xfc, 0x3f, 0x6e,
7068
+	0x2b, 0x10, 0x98, 0x3d, 0x2f, 0xd0, 0x0d, 0x10, 0x56, 0x63, 0xd4, 0x80, 0x62, 0x48, 0x46, 0x3e,
7069
+	0x23, 0xae, 0x2e, 0x94, 0x4b, 0x53, 0xff, 0x9a, 0x9b, 0xc1, 0x08, 0x27, 0xa0, 0xcd, 0xa5, 0xfd,
7070
+	0x83, 0xfa, 0x22, 0x54, 0xd2, 0x91, 0x3f, 0x36, 0xea, 0xbf, 0x19, 0x60, 0xed, 0x7c, 0x23, 0x68,
7071
+	0xa0, 0x3a, 0xf0, 0x7f, 0x65, 0xf0, 0x6b, 0xd3, 0xff, 0xac, 0xad, 0x63, 0x7f, 0x9a, 0xb3, 0x0e,
7072
+	0xb5, 0x65, 0x3f, 0x7b, 0x5e, 0x3d, 0xf7, 0xfb, 0xf3, 0xea, 0xb9, 0x6f, 0xc7, 0x55, 0xe3, 0xd9,
7073
+	0xb8, 0x6a, 0xfc, 0x3a, 0xae, 0x1a, 0x7f, 0x8c, 0xab, 0xc6, 0x5e, 0x41, 0xe5, 0xe7, 0xbd, 0xbf,
7074
+	0x03, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x7d, 0xca, 0x6a, 0x9f, 0x11, 0x00, 0x00,
7074 7075
 }
... ...
@@ -328,9 +328,7 @@ message Cluster {
328 328
 }
329 329
 
330 330
 // Secret represents a secret that should be passed to a container or a node,
331
-// and is immutable. It wraps the `spec` provided by the user with useful
332
-// information that is generated from the secret data in the `spec`, such as
333
-// the digest and size of the secret data.
331
+// and is immutable.
334 332
 message Secret {
335 333
 	option (docker.protobuf.plugin.store_object) = {
336 334
 		watch_selectors: {
... ...
@@ -355,6 +353,29 @@ message Secret {
355 355
 	bool internal = 4;
356 356
 }
357 357
 
358
+// Config represents a set of configuration files that should be passed to a
359
+// container.
360
+message Config {
361
+	option (docker.protobuf.plugin.store_object) = {
362
+		watch_selectors: {
363
+			id: true
364
+			id_prefix: true
365
+			name: true
366
+			name_prefix: true
367
+			custom: true
368
+			custom_prefix: true
369
+		}
370
+	};
371
+
372
+	string id = 1;
373
+
374
+	Meta meta = 2 [(gogoproto.nullable) = false];
375
+
376
+	// Spec contains the actual config data, as well as any context around the
377
+	// config data that the user provides.
378
+	ConfigSpec spec = 3  [(gogoproto.nullable) = false];
379
+}
380
+
358 381
 // Resource is a top-level object with externally defined content and indexing.
359 382
 // SwarmKit can serve as a store for these objects without understanding their
360 383
 // meanings.
... ...
@@ -175,6 +175,7 @@ type StoreAction struct {
175 175
 	//	*StoreAction_Secret
176 176
 	//	*StoreAction_Resource
177 177
 	//	*StoreAction_Extension
178
+	//	*StoreAction_Config
178 179
 	Target isStoreAction_Target `protobuf_oneof:"target"`
179 180
 }
180 181
 
... ...
@@ -212,6 +213,9 @@ type StoreAction_Resource struct {
212 212
 type StoreAction_Extension struct {
213 213
 	Extension *Extension `protobuf:"bytes,9,opt,name=extension,oneof"`
214 214
 }
215
+type StoreAction_Config struct {
216
+	Config *Config `protobuf:"bytes,10,opt,name=config,oneof"`
217
+}
215 218
 
216 219
 func (*StoreAction_Node) isStoreAction_Target()      {}
217 220
 func (*StoreAction_Service) isStoreAction_Target()   {}
... ...
@@ -221,6 +225,7 @@ func (*StoreAction_Cluster) isStoreAction_Target()   {}
221 221
 func (*StoreAction_Secret) isStoreAction_Target()    {}
222 222
 func (*StoreAction_Resource) isStoreAction_Target()  {}
223 223
 func (*StoreAction_Extension) isStoreAction_Target() {}
224
+func (*StoreAction_Config) isStoreAction_Target()    {}
224 225
 
225 226
 func (m *StoreAction) GetTarget() isStoreAction_Target {
226 227
 	if m != nil {
... ...
@@ -285,6 +290,13 @@ func (m *StoreAction) GetExtension() *Extension {
285 285
 	return nil
286 286
 }
287 287
 
288
+func (m *StoreAction) GetConfig() *Config {
289
+	if x, ok := m.GetTarget().(*StoreAction_Config); ok {
290
+		return x.Config
291
+	}
292
+	return nil
293
+}
294
+
288 295
 // XXX_OneofFuncs is for the internal use of the proto package.
289 296
 func (*StoreAction) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
290 297
 	return _StoreAction_OneofMarshaler, _StoreAction_OneofUnmarshaler, _StoreAction_OneofSizer, []interface{}{
... ...
@@ -296,6 +308,7 @@ func (*StoreAction) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) e
296 296
 		(*StoreAction_Secret)(nil),
297 297
 		(*StoreAction_Resource)(nil),
298 298
 		(*StoreAction_Extension)(nil),
299
+		(*StoreAction_Config)(nil),
299 300
 	}
300 301
 }
301 302
 
... ...
@@ -343,6 +356,11 @@ func _StoreAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
343 343
 		if err := b.EncodeMessage(x.Extension); err != nil {
344 344
 			return err
345 345
 		}
346
+	case *StoreAction_Config:
347
+		_ = b.EncodeVarint(10<<3 | proto.WireBytes)
348
+		if err := b.EncodeMessage(x.Config); err != nil {
349
+			return err
350
+		}
346 351
 	case nil:
347 352
 	default:
348 353
 		return fmt.Errorf("StoreAction.Target has unexpected type %T", x)
... ...
@@ -417,6 +435,14 @@ func _StoreAction_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Bu
417 417
 		err := b.DecodeMessage(msg)
418 418
 		m.Target = &StoreAction_Extension{msg}
419 419
 		return true, err
420
+	case 10: // target.config
421
+		if wire != proto.WireBytes {
422
+			return true, proto.ErrInternalBadWireType
423
+		}
424
+		msg := new(Config)
425
+		err := b.DecodeMessage(msg)
426
+		m.Target = &StoreAction_Config{msg}
427
+		return true, err
420 428
 	default:
421 429
 		return false, nil
422 430
 	}
... ...
@@ -466,6 +492,11 @@ func _StoreAction_OneofSizer(msg proto.Message) (n int) {
466 466
 		n += proto.SizeVarint(9<<3 | proto.WireBytes)
467 467
 		n += proto.SizeVarint(uint64(s))
468 468
 		n += s
469
+	case *StoreAction_Config:
470
+		s := proto.Size(x.Config)
471
+		n += proto.SizeVarint(10<<3 | proto.WireBytes)
472
+		n += proto.SizeVarint(uint64(s))
473
+		n += s
469 474
 	case nil:
470 475
 	default:
471 476
 		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
... ...
@@ -757,6 +788,12 @@ func (m *StoreAction) CopyFrom(src interface{}) {
757 757
 			}
758 758
 			github_com_docker_swarmkit_api_deepcopy.Copy(v.Extension, o.GetExtension())
759 759
 			m.Target = &v
760
+		case *StoreAction_Config:
761
+			v := StoreAction_Config{
762
+				Config: &Config{},
763
+			}
764
+			github_com_docker_swarmkit_api_deepcopy.Copy(v.Config, o.GetConfig())
765
+			m.Target = &v
760 766
 		}
761 767
 	}
762 768
 
... ...
@@ -1409,6 +1446,20 @@ func (m *StoreAction_Extension) MarshalTo(dAtA []byte) (int, error) {
1409 1409
 	}
1410 1410
 	return i, nil
1411 1411
 }
1412
+func (m *StoreAction_Config) MarshalTo(dAtA []byte) (int, error) {
1413
+	i := 0
1414
+	if m.Config != nil {
1415
+		dAtA[i] = 0x52
1416
+		i++
1417
+		i = encodeVarintRaft(dAtA, i, uint64(m.Config.Size()))
1418
+		n15, err := m.Config.MarshalTo(dAtA[i:])
1419
+		if err != nil {
1420
+			return 0, err
1421
+		}
1422
+		i += n15
1423
+	}
1424
+	return i, nil
1425
+}
1412 1426
 func encodeFixed64Raft(dAtA []byte, offset int, v uint64) int {
1413 1427
 	dAtA[offset] = uint8(v)
1414 1428
 	dAtA[offset+1] = uint8(v >> 8)
... ...
@@ -1922,6 +1973,15 @@ func (m *StoreAction_Extension) Size() (n int) {
1922 1922
 	}
1923 1923
 	return n
1924 1924
 }
1925
+func (m *StoreAction_Config) Size() (n int) {
1926
+	var l int
1927
+	_ = l
1928
+	if m.Config != nil {
1929
+		l = m.Config.Size()
1930
+		n += 1 + l + sovRaft(uint64(l))
1931
+	}
1932
+	return n
1933
+}
1925 1934
 
1926 1935
 func sovRaft(x uint64) (n int) {
1927 1936
 	for {
... ...
@@ -2131,6 +2191,16 @@ func (this *StoreAction_Extension) String() string {
2131 2131
 	}, "")
2132 2132
 	return s
2133 2133
 }
2134
+func (this *StoreAction_Config) String() string {
2135
+	if this == nil {
2136
+		return "nil"
2137
+	}
2138
+	s := strings.Join([]string{`&StoreAction_Config{`,
2139
+		`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
2140
+		`}`,
2141
+	}, "")
2142
+	return s
2143
+}
2134 2144
 func valueToStringRaft(v interface{}) string {
2135 2145
 	rv := reflect.ValueOf(v)
2136 2146
 	if rv.IsNil() {
... ...
@@ -3355,6 +3425,38 @@ func (m *StoreAction) Unmarshal(dAtA []byte) error {
3355 3355
 			}
3356 3356
 			m.Target = &StoreAction_Extension{v}
3357 3357
 			iNdEx = postIndex
3358
+		case 10:
3359
+			if wireType != 2 {
3360
+				return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
3361
+			}
3362
+			var msglen int
3363
+			for shift := uint(0); ; shift += 7 {
3364
+				if shift >= 64 {
3365
+					return ErrIntOverflowRaft
3366
+				}
3367
+				if iNdEx >= l {
3368
+					return io.ErrUnexpectedEOF
3369
+				}
3370
+				b := dAtA[iNdEx]
3371
+				iNdEx++
3372
+				msglen |= (int(b) & 0x7F) << shift
3373
+				if b < 0x80 {
3374
+					break
3375
+				}
3376
+			}
3377
+			if msglen < 0 {
3378
+				return ErrInvalidLengthRaft
3379
+			}
3380
+			postIndex := iNdEx + msglen
3381
+			if postIndex > l {
3382
+				return io.ErrUnexpectedEOF
3383
+			}
3384
+			v := &Config{}
3385
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
3386
+				return err
3387
+			}
3388
+			m.Target = &StoreAction_Config{v}
3389
+			iNdEx = postIndex
3358 3390
 		default:
3359 3391
 			iNdEx = preIndex
3360 3392
 			skippy, err := skipRaft(dAtA[iNdEx:])
... ...
@@ -3484,64 +3586,65 @@ var (
3484 3484
 func init() { proto.RegisterFile("raft.proto", fileDescriptorRaft) }
3485 3485
 
3486 3486
 var fileDescriptorRaft = []byte{
3487
-	// 933 bytes of a gzipped FileDescriptorProto
3488
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x96, 0x41, 0x73, 0xdb, 0x44,
3489
-	0x14, 0xc7, 0x25, 0x5b, 0xb5, 0x9b, 0xe7, 0x26, 0xce, 0x6c, 0x48, 0x50, 0x45, 0x51, 0x5c, 0x95,
3490
-	0x99, 0xba, 0x1d, 0x22, 0x0f, 0x86, 0x19, 0x98, 0x42, 0x0f, 0x71, 0xe2, 0x19, 0x9b, 0xb6, 0x4e,
3491
-	0x47, 0x49, 0xa0, 0xb7, 0x20, 0x4b, 0x5b, 0x57, 0xd8, 0xd6, 0x9a, 0xdd, 0xb5, 0x03, 0x17, 0xa6,
3492
-	0x47, 0x26, 0x27, 0x66, 0x98, 0x01, 0x2e, 0x3d, 0xc1, 0xb9, 0x1f, 0x80, 0x4f, 0x90, 0xe1, 0xc4,
3493
-	0x0d, 0x4e, 0x19, 0xea, 0x0f, 0x00, 0x5f, 0x81, 0xd9, 0x95, 0x64, 0x07, 0x47, 0x76, 0x73, 0xb1,
3494
-	0xd7, 0xbb, 0xbf, 0xff, 0xfb, 0xef, 0xee, 0xd3, 0x7b, 0x32, 0x00, 0x75, 0x9f, 0x72, 0x7b, 0x40,
3495
-	0x09, 0x27, 0x08, 0xf9, 0xc4, 0xeb, 0x62, 0x6a, 0xb3, 0x63, 0x97, 0xf6, 0xbb, 0x01, 0xb7, 0x47,
3496
-	0xef, 0x19, 0xcb, 0xa4, 0xfd, 0x25, 0xf6, 0x38, 0x8b, 0x10, 0xa3, 0xc0, 0xbf, 0x19, 0xe0, 0xe4,
3497
-	0xc7, 0x56, 0x27, 0xe0, 0xcf, 0x86, 0x6d, 0xdb, 0x23, 0xfd, 0x8a, 0x47, 0x28, 0x26, 0xac, 0x82,
3498
-	0xb9, 0xe7, 0x57, 0x44, 0x48, 0xf9, 0x31, 0x68, 0x57, 0xa6, 0xe1, 0x8d, 0x37, 0x3a, 0xa4, 0x43,
3499
-	0xe4, 0xb0, 0x22, 0x46, 0xf1, 0xec, 0xda, 0xa0, 0x37, 0xec, 0x04, 0x61, 0x25, 0xfa, 0x8a, 0x26,
3500
-	0xad, 0x97, 0x2a, 0x80, 0xe3, 0x3e, 0xe5, 0x8f, 0x70, 0xbf, 0x8d, 0x29, 0xba, 0x05, 0x79, 0x11,
3501
-	0xe7, 0x28, 0xf0, 0x75, 0xb5, 0xa4, 0x96, 0xb5, 0x1a, 0x8c, 0xcf, 0x36, 0x73, 0x02, 0x68, 0xee,
3502
-	0x3a, 0x39, 0xb1, 0xd4, 0xf4, 0x05, 0x14, 0x12, 0x1f, 0x0b, 0x28, 0x53, 0x52, 0xcb, 0x4b, 0x11,
3503
-	0xd4, 0x22, 0x3e, 0x16, 0x90, 0x58, 0x6a, 0xfa, 0x08, 0x81, 0xe6, 0xfa, 0x3e, 0xd5, 0xb3, 0x82,
3504
-	0x70, 0xe4, 0x18, 0xd5, 0x20, 0xc7, 0xb8, 0xcb, 0x87, 0x4c, 0xd7, 0x4a, 0x6a, 0xb9, 0x50, 0x7d,
3505
-	0xc7, 0xbe, 0x78, 0x0f, 0xf6, 0x74, 0x37, 0xfb, 0x92, 0xad, 0x69, 0xa7, 0x67, 0x9b, 0x8a, 0x13,
3506
-	0x2b, 0xad, 0x9b, 0x50, 0xf8, 0x94, 0x04, 0xa1, 0x83, 0xbf, 0x1a, 0x62, 0xc6, 0x27, 0x36, 0xea,
3507
-	0xd4, 0xc6, 0xfa, 0x51, 0x85, 0x6b, 0x11, 0xc3, 0x06, 0x24, 0x64, 0xf8, 0x72, 0xa7, 0xfa, 0x08,
3508
-	0xf2, 0x7d, 0x69, 0xcb, 0xf4, 0x4c, 0x29, 0x5b, 0x2e, 0x54, 0xcd, 0xc5, 0xbb, 0x73, 0x12, 0x1c,
3509
-	0xdd, 0x86, 0x22, 0xc5, 0x7d, 0x32, 0xc2, 0xfe, 0x51, 0x12, 0x21, 0x5b, 0xca, 0x96, 0x35, 0x67,
3510
-	0x25, 0x9e, 0x8e, 0x04, 0xcc, 0xaa, 0xc1, 0xb5, 0x87, 0xd8, 0x1d, 0xe1, 0x64, 0xf3, 0x55, 0xd0,
3511
-	0xc4, 0x6d, 0xc9, 0x4d, 0xbd, 0xde, 0x4f, 0xb2, 0x56, 0x11, 0x96, 0xe3, 0x18, 0xd1, 0xe1, 0xac,
3512
-	0x87, 0x70, 0xfd, 0x31, 0x25, 0x1e, 0x66, 0x2c, 0x62, 0x19, 0x73, 0x3b, 0x13, 0x87, 0x3b, 0xe2,
3513
-	0x50, 0x72, 0x26, 0x36, 0x29, 0xda, 0xd1, 0xe3, 0x62, 0x27, 0x60, 0xb2, 0x7e, 0x4f, 0x7b, 0xfe,
3514
-	0x93, 0xa5, 0x58, 0x37, 0xc0, 0x48, 0x8b, 0x16, 0x7b, 0x7d, 0x02, 0xeb, 0x0e, 0x66, 0xa4, 0x37,
3515
-	0xc2, 0xdb, 0xbe, 0x4f, 0x05, 0x14, 0xfb, 0x5c, 0xe6, 0x86, 0xad, 0x77, 0x61, 0x63, 0x56, 0x1d,
3516
-	0x27, 0x28, 0x2d, 0x8b, 0x3d, 0x58, 0x6b, 0x86, 0x1c, 0xd3, 0xd0, 0xed, 0x89, 0x38, 0x89, 0xd3,
3517
-	0x06, 0x64, 0x26, 0x26, 0xb9, 0xf1, 0xd9, 0x66, 0xa6, 0xb9, 0xeb, 0x64, 0x02, 0x1f, 0xdd, 0x87,
3518
-	0x9c, 0xeb, 0xf1, 0x80, 0x84, 0x71, 0xf6, 0x36, 0xd3, 0x6e, 0x73, 0x9f, 0x13, 0x8a, 0xb7, 0x25,
3519
-	0x96, 0x3c, 0x56, 0x91, 0xc8, 0xfa, 0x5e, 0x83, 0xc2, 0xb9, 0x55, 0xf4, 0xf1, 0x24, 0x9c, 0xb0,
3520
-	0x5a, 0xa9, 0xde, 0x7a, 0x4d, 0xb8, 0x07, 0x41, 0xe8, 0x27, 0xc1, 0x90, 0x1d, 0xe7, 0x35, 0x23,
3521
-	0xaf, 0x5c, 0x4f, 0x93, 0x8a, 0x6a, 0x69, 0x28, 0x51, 0x4e, 0xd1, 0x87, 0x90, 0x67, 0x98, 0x8e,
3522
-	0x02, 0x0f, 0xcb, 0x72, 0x29, 0x54, 0xdf, 0x4a, 0x75, 0x8b, 0x90, 0x86, 0xe2, 0x24, 0xb4, 0x30,
3523
-	0xe2, 0x2e, 0xeb, 0xc6, 0xe5, 0x94, 0x6a, 0x74, 0xe0, 0xb2, 0xae, 0x30, 0x12, 0x9c, 0x30, 0x0a,
3524
-	0x31, 0x3f, 0x26, 0xb4, 0xab, 0x5f, 0x99, 0x6f, 0xd4, 0x8a, 0x10, 0x61, 0x14, 0xd3, 0x42, 0xe8,
3525
-	0xf5, 0x86, 0x8c, 0x63, 0xaa, 0xe7, 0xe6, 0x0b, 0x77, 0x22, 0x44, 0x08, 0x63, 0x1a, 0x7d, 0x00,
3526
-	0x39, 0x86, 0x3d, 0x8a, 0xb9, 0x9e, 0x97, 0x3a, 0x23, 0xfd, 0x64, 0x82, 0x68, 0x88, 0x22, 0x97,
3527
-	0x23, 0x74, 0x0f, 0xae, 0x52, 0xcc, 0xc8, 0x90, 0x7a, 0x58, 0xbf, 0x2a, 0x75, 0x37, 0x52, 0x8b,
3528
-	0x23, 0x66, 0x1a, 0x8a, 0x33, 0xe1, 0xd1, 0x7d, 0x58, 0xc2, 0x5f, 0x73, 0x1c, 0x32, 0x91, 0xbc,
3529
-	0x25, 0x29, 0x7e, 0x3b, 0x4d, 0x5c, 0x4f, 0xa0, 0x86, 0xe2, 0x4c, 0x15, 0xb5, 0xab, 0x90, 0xe3,
3530
-	0x2e, 0xed, 0x60, 0x7e, 0xf7, 0x5f, 0x15, 0x8a, 0x33, 0x19, 0x46, 0xb7, 0x21, 0x7f, 0xd8, 0x7a,
3531
-	0xd0, 0xda, 0xfb, 0xbc, 0xb5, 0xaa, 0x18, 0xc6, 0xc9, 0x8b, 0xd2, 0xc6, 0x0c, 0x71, 0x18, 0x76,
3532
-	0x43, 0x72, 0x1c, 0xa2, 0x2a, 0xac, 0xed, 0x1f, 0xec, 0x39, 0xf5, 0xa3, 0xed, 0x9d, 0x83, 0xe6,
3533
-	0x5e, 0xeb, 0x68, 0xc7, 0xa9, 0x6f, 0x1f, 0xd4, 0x57, 0x55, 0xe3, 0xfa, 0xc9, 0x8b, 0xd2, 0xfa,
3534
-	0x8c, 0x68, 0x87, 0x62, 0x97, 0xe3, 0x0b, 0x9a, 0xc3, 0xc7, 0xbb, 0x42, 0x93, 0x49, 0xd5, 0x1c,
3535
-	0x0e, 0xfc, 0x34, 0x8d, 0x53, 0x7f, 0xb4, 0xf7, 0x59, 0x7d, 0x35, 0x9b, 0xaa, 0x71, 0x64, 0x3b,
3536
-	0x32, 0xde, 0xfc, 0xee, 0x17, 0x53, 0xf9, 0xed, 0x57, 0x73, 0xf6, 0x74, 0xd5, 0x1f, 0x32, 0xa0,
3537
-	0x89, 0x5a, 0x43, 0x27, 0x2a, 0xa0, 0x8b, 0x6d, 0x00, 0x6d, 0xa5, 0xdd, 0xe3, 0xdc, 0xe6, 0x63,
3538
-	0xd8, 0x97, 0xc5, 0xe3, 0xee, 0xb2, 0xfe, 0xfb, 0xcb, 0x7f, 0x7e, 0xce, 0x14, 0x61, 0x59, 0xf2,
3539
-	0x5b, 0x7d, 0x37, 0x74, 0x3b, 0x98, 0xa2, 0x6f, 0x61, 0xe5, 0xff, 0x6d, 0x03, 0xdd, 0x99, 0xf7,
3540
-	0x30, 0x5c, 0x68, 0x4c, 0xc6, 0xdd, 0xcb, 0xa0, 0x0b, 0xfd, 0xab, 0x7f, 0xaa, 0xb0, 0x32, 0x6d,
3541
-	0xc3, 0xec, 0x59, 0x30, 0x40, 0x5f, 0x80, 0x26, 0x5e, 0x30, 0x28, 0xb5, 0xc9, 0x9c, 0x7b, 0x3d,
3542
-	0x19, 0xa5, 0xf9, 0xc0, 0xe2, 0x43, 0x7b, 0x70, 0x45, 0xb6, 0x79, 0x94, 0x1a, 0xe1, 0xfc, 0x5b,
3543
-	0xc4, 0xb8, 0xb9, 0x80, 0x58, 0x68, 0x52, 0xd3, 0x4f, 0x5f, 0x99, 0xca, 0x5f, 0xaf, 0x4c, 0xe5,
3544
-	0xf9, 0xd8, 0x54, 0x4f, 0xc7, 0xa6, 0xfa, 0xc7, 0xd8, 0x54, 0xff, 0x1e, 0x9b, 0xea, 0x93, 0xec,
3545
-	0x13, 0xad, 0x9d, 0x93, 0xff, 0x10, 0xde, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x98, 0x55, 0x8d,
3546
-	0x81, 0xb9, 0x08, 0x00, 0x00,
3487
+	// 949 bytes of a gzipped FileDescriptorProto
3488
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x96, 0x4f, 0x6f, 0x1b, 0x45,
3489
+	0x18, 0xc6, 0x77, 0xed, 0xad, 0x9d, 0xbc, 0x6e, 0xe2, 0x68, 0x42, 0xc2, 0x76, 0x29, 0x8e, 0xbb,
3490
+	0x45, 0xaa, 0x5b, 0x91, 0xb5, 0x30, 0x48, 0xa0, 0x42, 0x0f, 0xb1, 0x63, 0xc9, 0xa6, 0xad, 0x53,
3491
+	0x6d, 0x12, 0xe8, 0x2d, 0xac, 0x77, 0x27, 0xee, 0x62, 0x7b, 0xc7, 0xcc, 0x8c, 0x1d, 0xb8, 0xa0,
3492
+	0x1e, 0x51, 0xae, 0x48, 0xc0, 0xa5, 0x27, 0x38, 0xf7, 0x03, 0xf0, 0x01, 0x50, 0xc4, 0x89, 0x1b,
3493
+	0x9c, 0x22, 0xea, 0x0f, 0x00, 0x5f, 0x01, 0xcd, 0xec, 0xae, 0x1d, 0x9c, 0xb5, 0x9b, 0x8b, 0x3d,
3494
+	0x9e, 0xf9, 0x3d, 0xef, 0xf3, 0xce, 0xbf, 0x77, 0x0c, 0x40, 0x9d, 0x63, 0x6e, 0x0d, 0x28, 0xe1,
3495
+	0x04, 0x21, 0x8f, 0xb8, 0x5d, 0x4c, 0x2d, 0x76, 0xe2, 0xd0, 0x7e, 0xd7, 0xe7, 0xd6, 0xe8, 0x3d,
3496
+	0x63, 0x85, 0xb4, 0xbf, 0xc4, 0x2e, 0x67, 0x21, 0x62, 0xe4, 0xf8, 0x37, 0x03, 0x1c, 0xff, 0xd8,
3497
+	0xee, 0xf8, 0xfc, 0xd9, 0xb0, 0x6d, 0xb9, 0xa4, 0x5f, 0x76, 0x09, 0xc5, 0x84, 0x95, 0x31, 0x77,
3498
+	0xbd, 0xb2, 0x08, 0x29, 0x3f, 0x06, 0xed, 0xf2, 0x34, 0xbc, 0xf1, 0x46, 0x87, 0x74, 0x88, 0x6c,
3499
+	0x96, 0x45, 0x2b, 0xea, 0x5d, 0x1f, 0xf4, 0x86, 0x1d, 0x3f, 0x28, 0x87, 0x5f, 0x61, 0xa7, 0xf9,
3500
+	0x52, 0x05, 0xb0, 0x9d, 0x63, 0xfe, 0x18, 0xf7, 0xdb, 0x98, 0xa2, 0xdb, 0x90, 0x15, 0x71, 0x8e,
3501
+	0x7c, 0x4f, 0x57, 0x8b, 0x6a, 0x49, 0xab, 0xc2, 0xf8, 0x7c, 0x2b, 0x23, 0x80, 0xe6, 0xae, 0x9d,
3502
+	0x11, 0x43, 0x4d, 0x4f, 0x40, 0x01, 0xf1, 0xb0, 0x80, 0x52, 0x45, 0xb5, 0xb4, 0x1c, 0x42, 0x2d,
3503
+	0xe2, 0x61, 0x01, 0x89, 0xa1, 0xa6, 0x87, 0x10, 0x68, 0x8e, 0xe7, 0x51, 0x3d, 0x2d, 0x08, 0x5b,
3504
+	0xb6, 0x51, 0x15, 0x32, 0x8c, 0x3b, 0x7c, 0xc8, 0x74, 0xad, 0xa8, 0x96, 0x72, 0x95, 0x77, 0xac,
3505
+	0xcb, 0xeb, 0x60, 0x4d, 0xb3, 0xd9, 0x97, 0x6c, 0x55, 0x3b, 0x3b, 0xdf, 0x52, 0xec, 0x48, 0x69,
3506
+	0xde, 0x82, 0xdc, 0xa7, 0xc4, 0x0f, 0x6c, 0xfc, 0xd5, 0x10, 0x33, 0x3e, 0xb1, 0x51, 0xa7, 0x36,
3507
+	0xe6, 0x0f, 0x2a, 0x5c, 0x0f, 0x19, 0x36, 0x20, 0x01, 0xc3, 0x57, 0x9b, 0xd5, 0x47, 0x90, 0xed,
3508
+	0x4b, 0x5b, 0xa6, 0xa7, 0x8a, 0xe9, 0x52, 0xae, 0x52, 0x58, 0x9c, 0x9d, 0x1d, 0xe3, 0xe8, 0x0e,
3509
+	0xe4, 0x29, 0xee, 0x93, 0x11, 0xf6, 0x8e, 0xe2, 0x08, 0xe9, 0x62, 0xba, 0xa4, 0xd9, 0xab, 0x51,
3510
+	0x77, 0x28, 0x60, 0x66, 0x15, 0xae, 0x3f, 0xc2, 0xce, 0x08, 0xc7, 0xc9, 0x57, 0x40, 0x13, 0xab,
3511
+	0x25, 0x93, 0x7a, 0xbd, 0x9f, 0x64, 0xcd, 0x3c, 0xac, 0x44, 0x31, 0xc2, 0xc9, 0x99, 0x8f, 0xe0,
3512
+	0xc6, 0x13, 0x4a, 0x5c, 0xcc, 0x58, 0xc8, 0x32, 0xe6, 0x74, 0x26, 0x0e, 0x77, 0xc5, 0xa4, 0x64,
3513
+	0x4f, 0x64, 0x92, 0xb7, 0xc2, 0xe3, 0x62, 0xc5, 0x60, 0x3c, 0x7e, 0x5f, 0x7b, 0xfe, 0xa3, 0xa9,
3514
+	0x98, 0x37, 0xc1, 0x48, 0x8a, 0x16, 0x79, 0x7d, 0x02, 0x1b, 0x36, 0x66, 0xa4, 0x37, 0xc2, 0x3b,
3515
+	0x9e, 0x47, 0x05, 0x14, 0xf9, 0x5c, 0x65, 0x85, 0xcd, 0x77, 0x61, 0x73, 0x56, 0x1d, 0x6d, 0x50,
3516
+	0xd2, 0x2e, 0xf6, 0x60, 0xbd, 0x19, 0x70, 0x4c, 0x03, 0xa7, 0x27, 0xe2, 0xc4, 0x4e, 0x9b, 0x90,
3517
+	0x9a, 0x98, 0x64, 0xc6, 0xe7, 0x5b, 0xa9, 0xe6, 0xae, 0x9d, 0xf2, 0x3d, 0xf4, 0x00, 0x32, 0x8e,
3518
+	0xcb, 0x7d, 0x12, 0x44, 0xbb, 0xb7, 0x95, 0xb4, 0x9a, 0xfb, 0x9c, 0x50, 0xbc, 0x23, 0xb1, 0xf8,
3519
+	0x58, 0x85, 0x22, 0xf3, 0x37, 0x0d, 0x72, 0x17, 0x46, 0xd1, 0xc7, 0x93, 0x70, 0xc2, 0x6a, 0xb5,
3520
+	0x72, 0xfb, 0x35, 0xe1, 0x1e, 0xfa, 0x81, 0x17, 0x07, 0x43, 0x56, 0xb4, 0xaf, 0x29, 0xb9, 0xe4,
3521
+	0x7a, 0x92, 0x54, 0xdc, 0x96, 0x86, 0x12, 0xee, 0x29, 0xfa, 0x10, 0xb2, 0x0c, 0xd3, 0x91, 0xef,
3522
+	0x62, 0x79, 0x5d, 0x72, 0x95, 0xb7, 0x12, 0xdd, 0x42, 0xa4, 0xa1, 0xd8, 0x31, 0x2d, 0x8c, 0xb8,
3523
+	0xc3, 0xba, 0xd1, 0x75, 0x4a, 0x34, 0x3a, 0x70, 0x58, 0x57, 0x18, 0x09, 0x4e, 0x18, 0x05, 0x98,
3524
+	0x9f, 0x10, 0xda, 0xd5, 0xaf, 0xcd, 0x37, 0x6a, 0x85, 0x88, 0x30, 0x8a, 0x68, 0x21, 0x74, 0x7b,
3525
+	0x43, 0xc6, 0x31, 0xd5, 0x33, 0xf3, 0x85, 0xb5, 0x10, 0x11, 0xc2, 0x88, 0x46, 0x1f, 0x40, 0x86,
3526
+	0x61, 0x97, 0x62, 0xae, 0x67, 0xa5, 0xce, 0x48, 0x9e, 0x99, 0x20, 0x1a, 0xe2, 0x92, 0xcb, 0x16,
3527
+	0xba, 0x0f, 0x4b, 0x14, 0x33, 0x32, 0xa4, 0x2e, 0xd6, 0x97, 0xa4, 0xee, 0x66, 0xe2, 0xe5, 0x88,
3528
+	0x98, 0x86, 0x62, 0x4f, 0x78, 0xf4, 0x00, 0x96, 0xf1, 0xd7, 0x1c, 0x07, 0x4c, 0x6c, 0xde, 0xb2,
3529
+	0x14, 0xbf, 0x9d, 0x24, 0xae, 0xc7, 0x50, 0x43, 0xb1, 0xa7, 0x0a, 0x91, 0xb0, 0x4b, 0x82, 0x63,
3530
+	0xbf, 0xa3, 0xc3, 0xfc, 0x84, 0x6b, 0x92, 0x10, 0x09, 0x87, 0x6c, 0x75, 0x09, 0x32, 0xdc, 0xa1,
3531
+	0x1d, 0xcc, 0xef, 0xfd, 0xab, 0x42, 0x7e, 0xe6, 0x5c, 0xa0, 0x3b, 0x90, 0x3d, 0x6c, 0x3d, 0x6c,
3532
+	0xed, 0x7d, 0xde, 0x5a, 0x53, 0x0c, 0xe3, 0xf4, 0x45, 0x71, 0x73, 0x86, 0x38, 0x0c, 0xba, 0x01,
3533
+	0x39, 0x09, 0x50, 0x05, 0xd6, 0xf7, 0x0f, 0xf6, 0xec, 0xfa, 0xd1, 0x4e, 0xed, 0xa0, 0xb9, 0xd7,
3534
+	0x3a, 0xaa, 0xd9, 0xf5, 0x9d, 0x83, 0xfa, 0x9a, 0x6a, 0xdc, 0x38, 0x7d, 0x51, 0xdc, 0x98, 0x11,
3535
+	0xd5, 0x28, 0x76, 0x38, 0xbe, 0xa4, 0x39, 0x7c, 0xb2, 0x2b, 0x34, 0xa9, 0x44, 0xcd, 0xe1, 0xc0,
3536
+	0x4b, 0xd2, 0xd8, 0xf5, 0xc7, 0x7b, 0x9f, 0xd5, 0xd7, 0xd2, 0x89, 0x1a, 0x5b, 0x16, 0x31, 0xe3,
3537
+	0xcd, 0xef, 0x7e, 0x2e, 0x28, 0xbf, 0xfe, 0x52, 0x98, 0x9d, 0x5d, 0xe5, 0xfb, 0x14, 0x68, 0xe2,
3538
+	0x86, 0xa2, 0x53, 0x15, 0xd0, 0xe5, 0xe2, 0x81, 0xb6, 0x93, 0x56, 0x70, 0x6e, 0xc9, 0x32, 0xac,
3539
+	0xab, 0xe2, 0x51, 0x4d, 0xda, 0xf8, 0xfd, 0xe5, 0x3f, 0x3f, 0xa5, 0xf2, 0xb0, 0x22, 0xf9, 0xed,
3540
+	0xbe, 0x13, 0x38, 0x1d, 0x4c, 0xd1, 0xb7, 0xb0, 0xfa, 0xff, 0x62, 0x83, 0xee, 0xce, 0x3b, 0x42,
3541
+	0x97, 0xca, 0x99, 0x71, 0xef, 0x2a, 0xe8, 0x42, 0xff, 0xca, 0x9f, 0x2a, 0xac, 0x4e, 0x8b, 0x37,
3542
+	0x7b, 0xe6, 0x0f, 0xd0, 0x17, 0xa0, 0x89, 0x67, 0x09, 0x25, 0x96, 0xa6, 0x0b, 0x8f, 0x9a, 0x51,
3543
+	0x9c, 0x0f, 0x2c, 0x9e, 0xb4, 0x0b, 0xd7, 0xe4, 0xe3, 0x80, 0x12, 0x23, 0x5c, 0x7c, 0x7b, 0x8c,
3544
+	0x5b, 0x0b, 0x88, 0x85, 0x26, 0x55, 0xfd, 0xec, 0x55, 0x41, 0xf9, 0xeb, 0x55, 0x41, 0x79, 0x3e,
3545
+	0x2e, 0xa8, 0x67, 0xe3, 0x82, 0xfa, 0xc7, 0xb8, 0xa0, 0xfe, 0x3d, 0x2e, 0xa8, 0x4f, 0xd3, 0x4f,
3546
+	0xb5, 0x76, 0x46, 0xfe, 0xaf, 0x78, 0xff, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x31, 0xfd,
3547
+	0xe7, 0xef, 0x08, 0x00, 0x00,
3547 3548
 }
... ...
@@ -127,5 +127,6 @@ message StoreAction {
127 127
 		Secret secret = 7;
128 128
 		Resource resource = 8;
129 129
 		Extension extension = 9;
130
+		Config config = 10;
130 131
 	}
131 132
 }
... ...
@@ -51,6 +51,7 @@ type StoreSnapshot struct {
51 51
 	Secrets    []*Secret    `protobuf:"bytes,6,rep,name=secrets" json:"secrets,omitempty"`
52 52
 	Resources  []*Resource  `protobuf:"bytes,7,rep,name=resources" json:"resources,omitempty"`
53 53
 	Extensions []*Extension `protobuf:"bytes,8,rep,name=extensions" json:"extensions,omitempty"`
54
+	Configs    []*Config    `protobuf:"bytes,9,rep,name=configs" json:"configs,omitempty"`
54 55
 }
55 56
 
56 57
 func (m *StoreSnapshot) Reset()                    { *m = StoreSnapshot{} }
... ...
@@ -161,6 +162,14 @@ func (m *StoreSnapshot) CopyFrom(src interface{}) {
161 161
 		}
162 162
 	}
163 163
 
164
+	if o.Configs != nil {
165
+		m.Configs = make([]*Config, len(o.Configs))
166
+		for i := range m.Configs {
167
+			m.Configs[i] = &Config{}
168
+			github_com_docker_swarmkit_api_deepcopy.Copy(m.Configs[i], o.Configs[i])
169
+		}
170
+	}
171
+
164 172
 }
165 173
 
166 174
 func (m *ClusterSnapshot) Copy() *ClusterSnapshot {
... ...
@@ -319,6 +328,18 @@ func (m *StoreSnapshot) MarshalTo(dAtA []byte) (int, error) {
319 319
 			i += n
320 320
 		}
321 321
 	}
322
+	if len(m.Configs) > 0 {
323
+		for _, msg := range m.Configs {
324
+			dAtA[i] = 0x4a
325
+			i++
326
+			i = encodeVarintSnapshot(dAtA, i, uint64(msg.Size()))
327
+			n, err := msg.MarshalTo(dAtA[i:])
328
+			if err != nil {
329
+				return 0, err
330
+			}
331
+			i += n
332
+		}
333
+	}
322 334
 	return i, nil
323 335
 }
324 336
 
... ...
@@ -487,6 +508,12 @@ func (m *StoreSnapshot) Size() (n int) {
487 487
 			n += 1 + l + sovSnapshot(uint64(l))
488 488
 		}
489 489
 	}
490
+	if len(m.Configs) > 0 {
491
+		for _, e := range m.Configs {
492
+			l = e.Size()
493
+			n += 1 + l + sovSnapshot(uint64(l))
494
+		}
495
+	}
490 496
 	return n
491 497
 }
492 498
 
... ...
@@ -548,6 +575,7 @@ func (this *StoreSnapshot) String() string {
548 548
 		`Secrets:` + strings.Replace(fmt.Sprintf("%v", this.Secrets), "Secret", "Secret", 1) + `,`,
549 549
 		`Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`,
550 550
 		`Extensions:` + strings.Replace(fmt.Sprintf("%v", this.Extensions), "Extension", "Extension", 1) + `,`,
551
+		`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "Config", "Config", 1) + `,`,
551 552
 		`}`,
552 553
 	}, "")
553 554
 	return s
... ...
@@ -860,6 +888,37 @@ func (m *StoreSnapshot) Unmarshal(dAtA []byte) error {
860 860
 				return err
861 861
 			}
862 862
 			iNdEx = postIndex
863
+		case 9:
864
+			if wireType != 2 {
865
+				return fmt.Errorf("proto: wrong wireType = %d for field Configs", wireType)
866
+			}
867
+			var msglen int
868
+			for shift := uint(0); ; shift += 7 {
869
+				if shift >= 64 {
870
+					return ErrIntOverflowSnapshot
871
+				}
872
+				if iNdEx >= l {
873
+					return io.ErrUnexpectedEOF
874
+				}
875
+				b := dAtA[iNdEx]
876
+				iNdEx++
877
+				msglen |= (int(b) & 0x7F) << shift
878
+				if b < 0x80 {
879
+					break
880
+				}
881
+			}
882
+			if msglen < 0 {
883
+				return ErrInvalidLengthSnapshot
884
+			}
885
+			postIndex := iNdEx + msglen
886
+			if postIndex > l {
887
+				return io.ErrUnexpectedEOF
888
+			}
889
+			m.Configs = append(m.Configs, &Config{})
890
+			if err := m.Configs[len(m.Configs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
891
+				return err
892
+			}
893
+			iNdEx = postIndex
863 894
 		default:
864 895
 			iNdEx = preIndex
865 896
 			skippy, err := skipSnapshot(dAtA[iNdEx:])
... ...
@@ -1261,34 +1320,35 @@ var (
1261 1261
 func init() { proto.RegisterFile("snapshot.proto", fileDescriptorSnapshot) }
1262 1262
 
1263 1263
 var fileDescriptorSnapshot = []byte{
1264
-	// 449 bytes of a gzipped FileDescriptorProto
1265
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x93, 0xbf, 0x6f, 0xd3, 0x40,
1266
-	0x14, 0xc7, 0x73, 0xf9, 0xe5, 0xf0, 0xaa, 0x16, 0x38, 0x31, 0x9c, 0x02, 0x98, 0x10, 0x18, 0x32,
1267
-	0x19, 0x08, 0x48, 0x20, 0xa4, 0x32, 0x14, 0x31, 0x30, 0xd0, 0xe1, 0x82, 0x2a, 0x56, 0xc7, 0x79,
1268
-	0x6d, 0x83, 0x89, 0x2f, 0xba, 0x77, 0x75, 0x19, 0xf9, 0xf3, 0x22, 0xb1, 0x30, 0x32, 0x21, 0xea,
1269
-	0x85, 0x7f, 0x03, 0xdd, 0x9d, 0x6d, 0x22, 0xe1, 0x74, 0xbb, 0x44, 0x9f, 0xcf, 0xfb, 0xbe, 0xbb,
1270
-	0xf7, 0x0c, 0x07, 0x94, 0xc5, 0x6b, 0x3a, 0x57, 0x26, 0x5a, 0x6b, 0x65, 0x14, 0xe7, 0x0b, 0x95,
1271
-	0xa4, 0xa8, 0x23, 0xba, 0x8c, 0xf5, 0x2a, 0x5d, 0x9a, 0x28, 0x7f, 0x36, 0xdc, 0x57, 0xf3, 0xcf,
1272
-	0x98, 0x18, 0xf2, 0xc8, 0x10, 0x74, 0x7c, 0x5a, 0xe2, 0xc3, 0x3b, 0x67, 0xea, 0x4c, 0xb9, 0xe3,
1273
-	0x13, 0x7b, 0xf2, 0xff, 0x8e, 0xbf, 0x77, 0x60, 0x7f, 0x66, 0x94, 0xc6, 0x59, 0x59, 0x9c, 0x47,
1274
-	0xd0, 0xcb, 0xd4, 0x02, 0x49, 0xb0, 0x51, 0x67, 0xb2, 0x37, 0x15, 0xd1, 0xff, 0x31, 0xd1, 0xb1,
1275
-	0x5a, 0xa0, 0xf4, 0x18, 0x7f, 0x09, 0x03, 0x42, 0x9d, 0x2f, 0x13, 0x24, 0xd1, 0x76, 0xca, 0xdd,
1276
-	0x26, 0x65, 0xe6, 0x19, 0x59, 0xc3, 0x56, 0xcc, 0xd0, 0x5c, 0x2a, 0x9d, 0x92, 0xe8, 0xec, 0x16,
1277
-	0x8f, 0x3d, 0x23, 0x6b, 0xd8, 0x76, 0x68, 0x62, 0x4a, 0x49, 0x74, 0x77, 0x77, 0xf8, 0x31, 0xa6,
1278
-	0x54, 0x7a, 0xcc, 0x06, 0x25, 0x5f, 0x2e, 0xc8, 0xa0, 0x26, 0xd1, 0xdb, 0x1d, 0xf4, 0xd6, 0x33,
1279
-	0xb2, 0x86, 0xf9, 0x0b, 0x08, 0x08, 0x13, 0x8d, 0x86, 0x44, 0xdf, 0x79, 0xc3, 0xe6, 0x9b, 0x59,
1280
-	0x44, 0x56, 0x28, 0x7f, 0x0d, 0x37, 0x34, 0x92, 0xba, 0xd0, 0xf6, 0x45, 0x02, 0xe7, 0xdd, 0x6b,
1281
-	0xf2, 0x64, 0x09, 0xc9, 0x7f, 0x38, 0x3f, 0x04, 0xc0, 0xaf, 0x06, 0x33, 0x5a, 0xaa, 0x8c, 0xc4,
1282
-	0xc0, 0xc9, 0xf7, 0x9b, 0xe4, 0x77, 0x15, 0x25, 0xb7, 0x84, 0x31, 0xc2, 0xcd, 0xf2, 0x16, 0xf5,
1283
-	0x38, 0x5f, 0x41, 0xb0, 0xc2, 0xd5, 0xdc, 0xde, 0xdd, 0x0f, 0x34, 0x6c, 0xec, 0x25, 0x3e, 0x35,
1284
-	0x1f, 0x1c, 0x26, 0x2b, 0x9c, 0x0b, 0x08, 0x34, 0xae, 0x54, 0x8e, 0x0b, 0x37, 0xd7, 0xae, 0xac,
1285
-	0x7e, 0x8e, 0xff, 0x30, 0x18, 0xd4, 0x01, 0x6f, 0x20, 0xc8, 0x51, 0xdb, 0x7c, 0xc1, 0x46, 0x6c,
1286
-	0x72, 0x30, 0x7d, 0xdc, 0xf8, 0x48, 0xd5, 0xee, 0x9e, 0x78, 0x56, 0x56, 0x12, 0x7f, 0x0f, 0x50,
1287
-	0x26, 0x9e, 0x2f, 0xd7, 0xa2, 0x3d, 0x62, 0x93, 0xbd, 0xe9, 0xa3, 0x6b, 0xe6, 0x53, 0x55, 0x3a,
1288
-	0xea, 0x6e, 0x7e, 0x3d, 0x68, 0xc9, 0x2d, 0x99, 0x1f, 0x42, 0x8f, 0xec, 0x2e, 0x8b, 0x8e, 0xab,
1289
-	0xf2, 0xb0, 0xb1, 0x91, 0xed, 0x65, 0x2f, 0x6b, 0x78, 0x6b, 0x7c, 0x1b, 0x82, 0xb2, 0x3b, 0xde,
1290
-	0x87, 0xf6, 0xc9, 0xd3, 0x5b, 0xad, 0x23, 0xb1, 0xb9, 0x0a, 0x5b, 0x3f, 0xaf, 0xc2, 0xd6, 0xb7,
1291
-	0x22, 0x64, 0x9b, 0x22, 0x64, 0x3f, 0x8a, 0x90, 0xfd, 0x2e, 0x42, 0xf6, 0xa9, 0x3d, 0xef, 0xbb,
1292
-	0x2f, 0xe8, 0xf9, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x91, 0xfe, 0xed, 0x18, 0x98, 0x03, 0x00,
1293
-	0x00,
1264
+	// 466 bytes of a gzipped FileDescriptorProto
1265
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x93, 0x3f, 0x6f, 0x13, 0x4d,
1266
+	0x10, 0x87, 0xbd, 0xfe, 0x77, 0xce, 0x44, 0xc9, 0xfb, 0xb2, 0xa2, 0x58, 0x19, 0x38, 0x8c, 0xa1,
1267
+	0x70, 0x75, 0x80, 0x41, 0x02, 0x21, 0x85, 0x22, 0x11, 0x05, 0x05, 0x29, 0xd6, 0x28, 0xa2, 0x3d,
1268
+	0x9f, 0xc7, 0xce, 0x71, 0xf8, 0xd6, 0xda, 0xd9, 0x38, 0x94, 0xf0, 0xed, 0x5c, 0x52, 0x52, 0x21,
1269
+	0xe2, 0x86, 0xaf, 0x81, 0x76, 0xf7, 0xee, 0xb0, 0xc4, 0x99, 0x6e, 0x6d, 0x3d, 0xcf, 0xcc, 0x6f,
1270
+	0xf7, 0x66, 0xe0, 0x98, 0xf2, 0x78, 0x45, 0x97, 0xca, 0x44, 0x2b, 0xad, 0x8c, 0xe2, 0x7c, 0xa6,
1271
+	0x92, 0x0c, 0x75, 0x44, 0xd7, 0xb1, 0x5e, 0x66, 0xa9, 0x89, 0xd6, 0x4f, 0xfb, 0x47, 0x6a, 0xfa,
1272
+	0x11, 0x13, 0x43, 0x1e, 0xe9, 0x83, 0x8e, 0xe7, 0x05, 0xde, 0xbf, 0xbd, 0x50, 0x0b, 0xe5, 0x8e,
1273
+	0x8f, 0xed, 0xc9, 0xff, 0x3b, 0xfc, 0xda, 0x86, 0xa3, 0x89, 0x51, 0x1a, 0x27, 0x45, 0x71, 0x1e,
1274
+	0x41, 0x27, 0x57, 0x33, 0x24, 0xc1, 0x06, 0xad, 0xd1, 0xe1, 0x58, 0x44, 0x7f, 0xb7, 0x89, 0xce,
1275
+	0xd5, 0x0c, 0xa5, 0xc7, 0xf8, 0x0b, 0xe8, 0x11, 0xea, 0x75, 0x9a, 0x20, 0x89, 0xa6, 0x53, 0xee,
1276
+	0xd4, 0x29, 0x13, 0xcf, 0xc8, 0x0a, 0xb6, 0x62, 0x8e, 0xe6, 0x5a, 0xe9, 0x8c, 0x44, 0x6b, 0xbf,
1277
+	0x78, 0xee, 0x19, 0x59, 0xc1, 0x36, 0xa1, 0x89, 0x29, 0x23, 0xd1, 0xde, 0x9f, 0xf0, 0x7d, 0x4c,
1278
+	0x99, 0xf4, 0x98, 0x6d, 0x94, 0x7c, 0xba, 0x22, 0x83, 0x9a, 0x44, 0x67, 0x7f, 0xa3, 0x33, 0xcf,
1279
+	0xc8, 0x0a, 0xe6, 0xcf, 0x21, 0x20, 0x4c, 0x34, 0x1a, 0x12, 0x5d, 0xe7, 0xf5, 0xeb, 0x6f, 0x66,
1280
+	0x11, 0x59, 0xa2, 0xfc, 0x15, 0x1c, 0x68, 0x24, 0x75, 0xa5, 0xed, 0x8b, 0x04, 0xce, 0xbb, 0x5b,
1281
+	0xe7, 0xc9, 0x02, 0x92, 0x7f, 0x70, 0x7e, 0x02, 0x80, 0x9f, 0x0d, 0xe6, 0x94, 0xaa, 0x9c, 0x44,
1282
+	0xcf, 0xc9, 0xf7, 0xea, 0xe4, 0x37, 0x25, 0x25, 0x77, 0x04, 0x1b, 0x38, 0x51, 0xf9, 0x3c, 0x5d,
1283
+	0x90, 0x38, 0xd8, 0x1f, 0xf8, 0xcc, 0x21, 0xb2, 0x44, 0x87, 0x08, 0xff, 0x15, 0x77, 0xaf, 0x86,
1284
+	0xe0, 0x25, 0x04, 0x4b, 0x5c, 0x4e, 0xed, 0x8b, 0xf9, 0x31, 0x08, 0x6b, 0x6f, 0x10, 0xcf, 0xcd,
1285
+	0x3b, 0x87, 0xc9, 0x12, 0xe7, 0x02, 0x02, 0x8d, 0x4b, 0xb5, 0xc6, 0x99, 0x9b, 0x86, 0xb6, 0x2c,
1286
+	0x7f, 0x0e, 0x7f, 0x31, 0xe8, 0x55, 0x0d, 0x5e, 0x43, 0xb0, 0x46, 0x6d, 0x53, 0x0b, 0x36, 0x60,
1287
+	0xa3, 0xe3, 0xf1, 0xa3, 0xda, 0xa7, 0x2d, 0x27, 0xfe, 0xc2, 0xb3, 0xb2, 0x94, 0xf8, 0x5b, 0x80,
1288
+	0xa2, 0xe3, 0x65, 0xba, 0x12, 0xcd, 0x01, 0x1b, 0x1d, 0x8e, 0x1f, 0xfe, 0xe3, 0xab, 0x96, 0x95,
1289
+	0x4e, 0xdb, 0x9b, 0x1f, 0xf7, 0x1b, 0x72, 0x47, 0xe6, 0x27, 0xd0, 0x21, 0xbb, 0x01, 0xa2, 0xe5,
1290
+	0xaa, 0x3c, 0xa8, 0x0d, 0xb2, 0xbb, 0x22, 0x45, 0x0d, 0x6f, 0x0d, 0x6f, 0x41, 0x50, 0xa4, 0xe3,
1291
+	0x5d, 0x68, 0x5e, 0x3c, 0xf9, 0xbf, 0x71, 0x2a, 0x36, 0x37, 0x61, 0xe3, 0xfb, 0x4d, 0xd8, 0xf8,
1292
+	0xb2, 0x0d, 0xd9, 0x66, 0x1b, 0xb2, 0x6f, 0xdb, 0x90, 0xfd, 0xdc, 0x86, 0xec, 0x43, 0x73, 0xda,
1293
+	0x75, 0x7b, 0xf7, 0xec, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x41, 0x5b, 0x51, 0xce, 0x03,
1294
+	0x00, 0x00,
1294 1295
 }
... ...
@@ -22,6 +22,7 @@ message StoreSnapshot {
22 22
 	repeated Secret secrets = 6;
23 23
 	repeated Resource resources = 7;
24 24
 	repeated Extension extensions = 8;
25
+	repeated Config configs = 9;
25 26
 }
26 27
 
27 28
 // ClusterSnapshot stores cluster membership information in snapshots.
... ...
@@ -522,6 +522,8 @@ type ContainerSpec struct {
522 522
 	User string `protobuf:"bytes,7,opt,name=user,proto3" json:"user,omitempty"`
523 523
 	// Groups specifies supplementary groups available to the user.
524 524
 	Groups []string `protobuf:"bytes,11,rep,name=groups" json:"groups,omitempty"`
525
+	// Privileges specifies security configuration/permissions.
526
+	Privileges *Privileges `protobuf:"bytes,22,opt,name=privileges" json:"privileges,omitempty"`
525 527
 	// TTY declares that a TTY should be attached to the standard streams,
526 528
 	// including stdin if it is still open.
527 529
 	TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
... ...
@@ -544,6 +546,9 @@ type ContainerSpec struct {
544 544
 	// SecretReference contains references to zero or more secrets that
545 545
 	// will be exposed to the container.
546 546
 	Secrets []*SecretReference `protobuf:"bytes,12,rep,name=secrets" json:"secrets,omitempty"`
547
+	// ConfigReference contains references to zero or more configs that
548
+	// will be exposed to the container.
549
+	Configs []*ConfigReference `protobuf:"bytes,21,rep,name=configs" json:"configs,omitempty"`
547 550
 	// Hosts allow additional entries to be specified in /etc/hosts
548 551
 	// that associates IP addresses with hostnames.
549 552
 	// Detailed documentation is available in:
... ...
@@ -679,6 +684,19 @@ func (m *SecretSpec) Reset()                    { *m = SecretSpec{} }
679 679
 func (*SecretSpec) ProtoMessage()               {}
680 680
 func (*SecretSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{11} }
681 681
 
682
+// ConfigSpec specifies user-provided configuration files.
683
+type ConfigSpec struct {
684
+	Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"`
685
+	// Data is the config payload - the maximum size is 500KB (that is, 500*1024 bytes)
686
+	// TODO(aaronl): Do we want to revise this to include multiple payloads in a single
687
+	// ConfigSpec? Define this to be a tar? etc...
688
+	Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
689
+}
690
+
691
+func (m *ConfigSpec) Reset()                    { *m = ConfigSpec{} }
692
+func (*ConfigSpec) ProtoMessage()               {}
693
+func (*ConfigSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{12} }
694
+
682 695
 func init() {
683 696
 	proto.RegisterType((*NodeSpec)(nil), "docker.swarmkit.v1.NodeSpec")
684 697
 	proto.RegisterType((*ServiceSpec)(nil), "docker.swarmkit.v1.ServiceSpec")
... ...
@@ -694,6 +712,7 @@ func init() {
694 694
 	proto.RegisterType((*NetworkSpec)(nil), "docker.swarmkit.v1.NetworkSpec")
695 695
 	proto.RegisterType((*ClusterSpec)(nil), "docker.swarmkit.v1.ClusterSpec")
696 696
 	proto.RegisterType((*SecretSpec)(nil), "docker.swarmkit.v1.SecretSpec")
697
+	proto.RegisterType((*ConfigSpec)(nil), "docker.swarmkit.v1.ConfigSpec")
697 698
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Membership", NodeSpec_Membership_name, NodeSpec_Membership_value)
698 699
 	proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Availability", NodeSpec_Availability_name, NodeSpec_Availability_value)
699 700
 	proto.RegisterEnum("docker.swarmkit.v1.EndpointSpec_ResolutionMode", EndpointSpec_ResolutionMode_name, EndpointSpec_ResolutionMode_value)
... ...
@@ -930,6 +949,10 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
930 930
 		copy(m.Groups, o.Groups)
931 931
 	}
932 932
 
933
+	if o.Privileges != nil {
934
+		m.Privileges = &Privileges{}
935
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.Privileges, o.Privileges)
936
+	}
933 937
 	if o.Mounts != nil {
934 938
 		m.Mounts = make([]Mount, len(o.Mounts))
935 939
 		for i := range m.Mounts {
... ...
@@ -953,6 +976,14 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
953 953
 		}
954 954
 	}
955 955
 
956
+	if o.Configs != nil {
957
+		m.Configs = make([]*ConfigReference, len(o.Configs))
958
+		for i := range m.Configs {
959
+			m.Configs[i] = &ConfigReference{}
960
+			github_com_docker_swarmkit_api_deepcopy.Copy(m.Configs[i], o.Configs[i])
961
+		}
962
+	}
963
+
956 964
 	if o.Hosts != nil {
957 965
 		m.Hosts = make([]string, len(o.Hosts))
958 966
 		copy(m.Hosts, o.Hosts)
... ...
@@ -1103,6 +1134,26 @@ func (m *SecretSpec) CopyFrom(src interface{}) {
1103 1103
 	}
1104 1104
 }
1105 1105
 
1106
+func (m *ConfigSpec) Copy() *ConfigSpec {
1107
+	if m == nil {
1108
+		return nil
1109
+	}
1110
+	o := &ConfigSpec{}
1111
+	o.CopyFrom(m)
1112
+	return o
1113
+}
1114
+
1115
+func (m *ConfigSpec) CopyFrom(src interface{}) {
1116
+
1117
+	o := src.(*ConfigSpec)
1118
+	*m = *o
1119
+	github_com_docker_swarmkit_api_deepcopy.Copy(&m.Annotations, &o.Annotations)
1120
+	if o.Data != nil {
1121
+		m.Data = make([]byte, len(o.Data))
1122
+		copy(m.Data, o.Data)
1123
+	}
1124
+}
1125
+
1106 1126
 func (m *NodeSpec) Marshal() (dAtA []byte, err error) {
1107 1127
 	size := m.Size()
1108 1128
 	dAtA = make([]byte, size)
... ...
@@ -1719,6 +1770,32 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
1719 1719
 		i = encodeVarintSpecs(dAtA, i, uint64(len(m.StopSignal)))
1720 1720
 		i += copy(dAtA[i:], m.StopSignal)
1721 1721
 	}
1722
+	if len(m.Configs) > 0 {
1723
+		for _, msg := range m.Configs {
1724
+			dAtA[i] = 0xaa
1725
+			i++
1726
+			dAtA[i] = 0x1
1727
+			i++
1728
+			i = encodeVarintSpecs(dAtA, i, uint64(msg.Size()))
1729
+			n, err := msg.MarshalTo(dAtA[i:])
1730
+			if err != nil {
1731
+				return 0, err
1732
+			}
1733
+			i += n
1734
+		}
1735
+	}
1736
+	if m.Privileges != nil {
1737
+		dAtA[i] = 0xb2
1738
+		i++
1739
+		dAtA[i] = 0x1
1740
+		i++
1741
+		i = encodeVarintSpecs(dAtA, i, uint64(m.Privileges.Size()))
1742
+		n23, err := m.Privileges.MarshalTo(dAtA[i:])
1743
+		if err != nil {
1744
+			return 0, err
1745
+		}
1746
+		i += n23
1747
+	}
1722 1748
 	return i, nil
1723 1749
 }
1724 1750
 
... ...
@@ -1864,20 +1941,20 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
1864 1864
 	dAtA[i] = 0xa
1865 1865
 	i++
1866 1866
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
1867
-	n23, err := m.Annotations.MarshalTo(dAtA[i:])
1867
+	n24, err := m.Annotations.MarshalTo(dAtA[i:])
1868 1868
 	if err != nil {
1869 1869
 		return 0, err
1870 1870
 	}
1871
-	i += n23
1871
+	i += n24
1872 1872
 	if m.DriverConfig != nil {
1873 1873
 		dAtA[i] = 0x12
1874 1874
 		i++
1875 1875
 		i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
1876
-		n24, err := m.DriverConfig.MarshalTo(dAtA[i:])
1876
+		n25, err := m.DriverConfig.MarshalTo(dAtA[i:])
1877 1877
 		if err != nil {
1878 1878
 			return 0, err
1879 1879
 		}
1880
-		i += n24
1880
+		i += n25
1881 1881
 	}
1882 1882
 	if m.Ipv6Enabled {
1883 1883
 		dAtA[i] = 0x18
... ...
@@ -1903,11 +1980,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
1903 1903
 		dAtA[i] = 0x2a
1904 1904
 		i++
1905 1905
 		i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
1906
-		n25, err := m.IPAM.MarshalTo(dAtA[i:])
1906
+		n26, err := m.IPAM.MarshalTo(dAtA[i:])
1907 1907
 		if err != nil {
1908 1908
 			return 0, err
1909 1909
 		}
1910
-		i += n25
1910
+		i += n26
1911 1911
 	}
1912 1912
 	if m.Attachable {
1913 1913
 		dAtA[i] = 0x30
... ...
@@ -1950,67 +2027,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) {
1950 1950
 	dAtA[i] = 0xa
1951 1951
 	i++
1952 1952
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
1953
-	n26, err := m.Annotations.MarshalTo(dAtA[i:])
1953
+	n27, err := m.Annotations.MarshalTo(dAtA[i:])
1954 1954
 	if err != nil {
1955 1955
 		return 0, err
1956 1956
 	}
1957
-	i += n26
1957
+	i += n27
1958 1958
 	dAtA[i] = 0x12
1959 1959
 	i++
1960 1960
 	i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
1961
-	n27, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
1961
+	n28, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
1962 1962
 	if err != nil {
1963 1963
 		return 0, err
1964 1964
 	}
1965
-	i += n27
1965
+	i += n28
1966 1966
 	dAtA[i] = 0x1a
1967 1967
 	i++
1968 1968
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
1969
-	n28, err := m.Orchestration.MarshalTo(dAtA[i:])
1969
+	n29, err := m.Orchestration.MarshalTo(dAtA[i:])
1970 1970
 	if err != nil {
1971 1971
 		return 0, err
1972 1972
 	}
1973
-	i += n28
1973
+	i += n29
1974 1974
 	dAtA[i] = 0x22
1975 1975
 	i++
1976 1976
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
1977
-	n29, err := m.Raft.MarshalTo(dAtA[i:])
1977
+	n30, err := m.Raft.MarshalTo(dAtA[i:])
1978 1978
 	if err != nil {
1979 1979
 		return 0, err
1980 1980
 	}
1981
-	i += n29
1981
+	i += n30
1982 1982
 	dAtA[i] = 0x2a
1983 1983
 	i++
1984 1984
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
1985
-	n30, err := m.Dispatcher.MarshalTo(dAtA[i:])
1985
+	n31, err := m.Dispatcher.MarshalTo(dAtA[i:])
1986 1986
 	if err != nil {
1987 1987
 		return 0, err
1988 1988
 	}
1989
-	i += n30
1989
+	i += n31
1990 1990
 	dAtA[i] = 0x32
1991 1991
 	i++
1992 1992
 	i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
1993
-	n31, err := m.CAConfig.MarshalTo(dAtA[i:])
1993
+	n32, err := m.CAConfig.MarshalTo(dAtA[i:])
1994 1994
 	if err != nil {
1995 1995
 		return 0, err
1996 1996
 	}
1997
-	i += n31
1997
+	i += n32
1998 1998
 	dAtA[i] = 0x3a
1999 1999
 	i++
2000 2000
 	i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
2001
-	n32, err := m.TaskDefaults.MarshalTo(dAtA[i:])
2001
+	n33, err := m.TaskDefaults.MarshalTo(dAtA[i:])
2002 2002
 	if err != nil {
2003 2003
 		return 0, err
2004 2004
 	}
2005
-	i += n32
2005
+	i += n33
2006 2006
 	dAtA[i] = 0x42
2007 2007
 	i++
2008 2008
 	i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
2009
-	n33, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
2009
+	n34, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
2010 2010
 	if err != nil {
2011 2011
 		return 0, err
2012 2012
 	}
2013
-	i += n33
2013
+	i += n34
2014 2014
 	return i, nil
2015 2015
 }
2016 2016
 
... ...
@@ -2032,11 +2109,43 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
2032 2032
 	dAtA[i] = 0xa
2033 2033
 	i++
2034 2034
 	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
2035
-	n34, err := m.Annotations.MarshalTo(dAtA[i:])
2035
+	n35, err := m.Annotations.MarshalTo(dAtA[i:])
2036 2036
 	if err != nil {
2037 2037
 		return 0, err
2038 2038
 	}
2039
-	i += n34
2039
+	i += n35
2040
+	if len(m.Data) > 0 {
2041
+		dAtA[i] = 0x12
2042
+		i++
2043
+		i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data)))
2044
+		i += copy(dAtA[i:], m.Data)
2045
+	}
2046
+	return i, nil
2047
+}
2048
+
2049
+func (m *ConfigSpec) Marshal() (dAtA []byte, err error) {
2050
+	size := m.Size()
2051
+	dAtA = make([]byte, size)
2052
+	n, err := m.MarshalTo(dAtA)
2053
+	if err != nil {
2054
+		return nil, err
2055
+	}
2056
+	return dAtA[:n], nil
2057
+}
2058
+
2059
+func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) {
2060
+	var i int
2061
+	_ = i
2062
+	var l int
2063
+	_ = l
2064
+	dAtA[i] = 0xa
2065
+	i++
2066
+	i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
2067
+	n36, err := m.Annotations.MarshalTo(dAtA[i:])
2068
+	if err != nil {
2069
+		return 0, err
2070
+	}
2071
+	i += n36
2040 2072
 	if len(m.Data) > 0 {
2041 2073
 		dAtA[i] = 0x12
2042 2074
 		i++
... ...
@@ -2338,6 +2447,16 @@ func (m *ContainerSpec) Size() (n int) {
2338 2338
 	if l > 0 {
2339 2339
 		n += 2 + l + sovSpecs(uint64(l))
2340 2340
 	}
2341
+	if len(m.Configs) > 0 {
2342
+		for _, e := range m.Configs {
2343
+			l = e.Size()
2344
+			n += 2 + l + sovSpecs(uint64(l))
2345
+		}
2346
+	}
2347
+	if m.Privileges != nil {
2348
+		l = m.Privileges.Size()
2349
+		n += 2 + l + sovSpecs(uint64(l))
2350
+	}
2341 2351
 	return n
2342 2352
 }
2343 2353
 
... ...
@@ -2452,6 +2571,18 @@ func (m *SecretSpec) Size() (n int) {
2452 2452
 	return n
2453 2453
 }
2454 2454
 
2455
+func (m *ConfigSpec) Size() (n int) {
2456
+	var l int
2457
+	_ = l
2458
+	l = m.Annotations.Size()
2459
+	n += 1 + l + sovSpecs(uint64(l))
2460
+	l = len(m.Data)
2461
+	if l > 0 {
2462
+		n += 1 + l + sovSpecs(uint64(l))
2463
+	}
2464
+	return n
2465
+}
2466
+
2455 2467
 func sovSpecs(x uint64) (n int) {
2456 2468
 	for {
2457 2469
 		n++
... ...
@@ -2635,6 +2766,8 @@ func (this *ContainerSpec) String() string {
2635 2635
 		`OpenStdin:` + fmt.Sprintf("%v", this.OpenStdin) + `,`,
2636 2636
 		`ReadOnly:` + fmt.Sprintf("%v", this.ReadOnly) + `,`,
2637 2637
 		`StopSignal:` + fmt.Sprintf("%v", this.StopSignal) + `,`,
2638
+		`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "ConfigReference", "ConfigReference", 1) + `,`,
2639
+		`Privileges:` + strings.Replace(fmt.Sprintf("%v", this.Privileges), "Privileges", "Privileges", 1) + `,`,
2638 2640
 		`}`,
2639 2641
 	}, "")
2640 2642
 	return s
... ...
@@ -2716,6 +2849,17 @@ func (this *SecretSpec) String() string {
2716 2716
 	}, "")
2717 2717
 	return s
2718 2718
 }
2719
+func (this *ConfigSpec) String() string {
2720
+	if this == nil {
2721
+		return "nil"
2722
+	}
2723
+	s := strings.Join([]string{`&ConfigSpec{`,
2724
+		`Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`,
2725
+		`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
2726
+		`}`,
2727
+	}, "")
2728
+	return s
2729
+}
2719 2730
 func valueToStringSpecs(v interface{}) string {
2720 2731
 	rv := reflect.ValueOf(v)
2721 2732
 	if rv.IsNil() {
... ...
@@ -4492,6 +4636,70 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
4492 4492
 			}
4493 4493
 			m.StopSignal = string(dAtA[iNdEx:postIndex])
4494 4494
 			iNdEx = postIndex
4495
+		case 21:
4496
+			if wireType != 2 {
4497
+				return fmt.Errorf("proto: wrong wireType = %d for field Configs", wireType)
4498
+			}
4499
+			var msglen int
4500
+			for shift := uint(0); ; shift += 7 {
4501
+				if shift >= 64 {
4502
+					return ErrIntOverflowSpecs
4503
+				}
4504
+				if iNdEx >= l {
4505
+					return io.ErrUnexpectedEOF
4506
+				}
4507
+				b := dAtA[iNdEx]
4508
+				iNdEx++
4509
+				msglen |= (int(b) & 0x7F) << shift
4510
+				if b < 0x80 {
4511
+					break
4512
+				}
4513
+			}
4514
+			if msglen < 0 {
4515
+				return ErrInvalidLengthSpecs
4516
+			}
4517
+			postIndex := iNdEx + msglen
4518
+			if postIndex > l {
4519
+				return io.ErrUnexpectedEOF
4520
+			}
4521
+			m.Configs = append(m.Configs, &ConfigReference{})
4522
+			if err := m.Configs[len(m.Configs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
4523
+				return err
4524
+			}
4525
+			iNdEx = postIndex
4526
+		case 22:
4527
+			if wireType != 2 {
4528
+				return fmt.Errorf("proto: wrong wireType = %d for field Privileges", wireType)
4529
+			}
4530
+			var msglen int
4531
+			for shift := uint(0); ; shift += 7 {
4532
+				if shift >= 64 {
4533
+					return ErrIntOverflowSpecs
4534
+				}
4535
+				if iNdEx >= l {
4536
+					return io.ErrUnexpectedEOF
4537
+				}
4538
+				b := dAtA[iNdEx]
4539
+				iNdEx++
4540
+				msglen |= (int(b) & 0x7F) << shift
4541
+				if b < 0x80 {
4542
+					break
4543
+				}
4544
+			}
4545
+			if msglen < 0 {
4546
+				return ErrInvalidLengthSpecs
4547
+			}
4548
+			postIndex := iNdEx + msglen
4549
+			if postIndex > l {
4550
+				return io.ErrUnexpectedEOF
4551
+			}
4552
+			if m.Privileges == nil {
4553
+				m.Privileges = &Privileges{}
4554
+			}
4555
+			if err := m.Privileges.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
4556
+				return err
4557
+			}
4558
+			iNdEx = postIndex
4495 4559
 		default:
4496 4560
 			iNdEx = preIndex
4497 4561
 			skippy, err := skipSpecs(dAtA[iNdEx:])
... ...
@@ -5456,6 +5664,117 @@ func (m *SecretSpec) Unmarshal(dAtA []byte) error {
5456 5456
 	}
5457 5457
 	return nil
5458 5458
 }
5459
+func (m *ConfigSpec) Unmarshal(dAtA []byte) error {
5460
+	l := len(dAtA)
5461
+	iNdEx := 0
5462
+	for iNdEx < l {
5463
+		preIndex := iNdEx
5464
+		var wire uint64
5465
+		for shift := uint(0); ; shift += 7 {
5466
+			if shift >= 64 {
5467
+				return ErrIntOverflowSpecs
5468
+			}
5469
+			if iNdEx >= l {
5470
+				return io.ErrUnexpectedEOF
5471
+			}
5472
+			b := dAtA[iNdEx]
5473
+			iNdEx++
5474
+			wire |= (uint64(b) & 0x7F) << shift
5475
+			if b < 0x80 {
5476
+				break
5477
+			}
5478
+		}
5479
+		fieldNum := int32(wire >> 3)
5480
+		wireType := int(wire & 0x7)
5481
+		if wireType == 4 {
5482
+			return fmt.Errorf("proto: ConfigSpec: wiretype end group for non-group")
5483
+		}
5484
+		if fieldNum <= 0 {
5485
+			return fmt.Errorf("proto: ConfigSpec: illegal tag %d (wire type %d)", fieldNum, wire)
5486
+		}
5487
+		switch fieldNum {
5488
+		case 1:
5489
+			if wireType != 2 {
5490
+				return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType)
5491
+			}
5492
+			var msglen int
5493
+			for shift := uint(0); ; shift += 7 {
5494
+				if shift >= 64 {
5495
+					return ErrIntOverflowSpecs
5496
+				}
5497
+				if iNdEx >= l {
5498
+					return io.ErrUnexpectedEOF
5499
+				}
5500
+				b := dAtA[iNdEx]
5501
+				iNdEx++
5502
+				msglen |= (int(b) & 0x7F) << shift
5503
+				if b < 0x80 {
5504
+					break
5505
+				}
5506
+			}
5507
+			if msglen < 0 {
5508
+				return ErrInvalidLengthSpecs
5509
+			}
5510
+			postIndex := iNdEx + msglen
5511
+			if postIndex > l {
5512
+				return io.ErrUnexpectedEOF
5513
+			}
5514
+			if err := m.Annotations.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
5515
+				return err
5516
+			}
5517
+			iNdEx = postIndex
5518
+		case 2:
5519
+			if wireType != 2 {
5520
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
5521
+			}
5522
+			var byteLen int
5523
+			for shift := uint(0); ; shift += 7 {
5524
+				if shift >= 64 {
5525
+					return ErrIntOverflowSpecs
5526
+				}
5527
+				if iNdEx >= l {
5528
+					return io.ErrUnexpectedEOF
5529
+				}
5530
+				b := dAtA[iNdEx]
5531
+				iNdEx++
5532
+				byteLen |= (int(b) & 0x7F) << shift
5533
+				if b < 0x80 {
5534
+					break
5535
+				}
5536
+			}
5537
+			if byteLen < 0 {
5538
+				return ErrInvalidLengthSpecs
5539
+			}
5540
+			postIndex := iNdEx + byteLen
5541
+			if postIndex > l {
5542
+				return io.ErrUnexpectedEOF
5543
+			}
5544
+			m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
5545
+			if m.Data == nil {
5546
+				m.Data = []byte{}
5547
+			}
5548
+			iNdEx = postIndex
5549
+		default:
5550
+			iNdEx = preIndex
5551
+			skippy, err := skipSpecs(dAtA[iNdEx:])
5552
+			if err != nil {
5553
+				return err
5554
+			}
5555
+			if skippy < 0 {
5556
+				return ErrInvalidLengthSpecs
5557
+			}
5558
+			if (iNdEx + skippy) > l {
5559
+				return io.ErrUnexpectedEOF
5560
+			}
5561
+			iNdEx += skippy
5562
+		}
5563
+	}
5564
+
5565
+	if iNdEx > l {
5566
+		return io.ErrUnexpectedEOF
5567
+	}
5568
+	return nil
5569
+}
5459 5570
 func skipSpecs(dAtA []byte) (n int, err error) {
5460 5571
 	l := len(dAtA)
5461 5572
 	iNdEx := 0
... ...
@@ -5564,117 +5883,119 @@ var (
5564 5564
 func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
5565 5565
 
5566 5566
 var fileDescriptorSpecs = []byte{
5567
-	// 1779 bytes of a gzipped FileDescriptorProto
5568
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x41, 0x73, 0x1b, 0x49,
5569
-	0x15, 0xb6, 0x6c, 0x59, 0x1a, 0xbd, 0x91, 0x13, 0xb9, 0xc9, 0x2e, 0x63, 0x85, 0x95, 0x15, 0x6d,
5570
-	0x08, 0x5e, 0xb6, 0x90, 0x0b, 0x43, 0x2d, 0x59, 0xc2, 0x16, 0x48, 0x96, 0x70, 0x8c, 0xb1, 0xa3,
5571
-	0x6a, 0x7b, 0x03, 0x39, 0xa9, 0xda, 0x33, 0x6d, 0x69, 0xca, 0xa3, 0xee, 0xa1, 0xa7, 0xc7, 0x5b,
5572
-	0xba, 0x71, 0xdc, 0xca, 0x99, 0xab, 0x8b, 0x03, 0x7f, 0x26, 0x37, 0x28, 0x4e, 0x9c, 0x5c, 0xac,
5573
-	0xfe, 0x02, 0x3f, 0x00, 0xaa, 0x7b, 0x7a, 0xa4, 0x51, 0x32, 0x4e, 0x52, 0x45, 0x6e, 0xfd, 0x5e,
5574
-	0x7f, 0xdf, 0x9b, 0xd7, 0xaf, 0xbf, 0xee, 0xd7, 0x03, 0x76, 0x14, 0x52, 0x37, 0x6a, 0x87, 0x82,
5575
-	0x4b, 0x8e, 0x90, 0xc7, 0xdd, 0x4b, 0x2a, 0xda, 0xd1, 0x37, 0x44, 0x4c, 0x2e, 0x7d, 0xd9, 0xbe,
5576
-	0xfa, 0x69, 0xdd, 0x96, 0xd3, 0x90, 0x1a, 0x40, 0xfd, 0xde, 0x88, 0x8f, 0xb8, 0x1e, 0xee, 0xaa,
5577
-	0x91, 0xf1, 0x36, 0x46, 0x9c, 0x8f, 0x02, 0xba, 0xab, 0xad, 0xf3, 0xf8, 0x62, 0xd7, 0x8b, 0x05,
5578
-	0x91, 0x3e, 0x67, 0x66, 0x7e, 0xeb, 0xf5, 0x79, 0xc2, 0xa6, 0xc9, 0x54, 0xeb, 0xba, 0x08, 0xd6,
5579
-	0x09, 0xf7, 0xe8, 0x69, 0x48, 0x5d, 0x74, 0x00, 0x36, 0x61, 0x8c, 0x4b, 0xcd, 0x8d, 0x9c, 0x42,
5580
-	0xb3, 0xb0, 0x63, 0xef, 0x6d, 0xb7, 0xdf, 0x4c, 0xaa, 0xdd, 0x59, 0xc0, 0xba, 0xc5, 0x57, 0x37,
5581
-	0xdb, 0x2b, 0x38, 0xcb, 0x44, 0xbf, 0x86, 0xaa, 0x47, 0x23, 0x5f, 0x50, 0x6f, 0x28, 0x78, 0x40,
5582
-	0x9d, 0xd5, 0x66, 0x61, 0xe7, 0xce, 0xde, 0x0f, 0xf2, 0x22, 0xa9, 0x8f, 0x63, 0x1e, 0x50, 0x6c,
5583
-	0x1b, 0x86, 0x32, 0xd0, 0x01, 0xc0, 0x84, 0x4e, 0xce, 0xa9, 0x88, 0xc6, 0x7e, 0xe8, 0xac, 0x69,
5584
-	0xfa, 0x8f, 0x6e, 0xa3, 0xab, 0xdc, 0xdb, 0xc7, 0x73, 0x38, 0xce, 0x50, 0xd1, 0x31, 0x54, 0xc9,
5585
-	0x15, 0xf1, 0x03, 0x72, 0xee, 0x07, 0xbe, 0x9c, 0x3a, 0x45, 0x1d, 0xea, 0xb3, 0xb7, 0x86, 0xea,
5586
-	0x64, 0x08, 0x78, 0x89, 0xde, 0xf2, 0x00, 0x16, 0x1f, 0x42, 0x8f, 0xa0, 0x3c, 0xe8, 0x9f, 0xf4,
5587
-	0x0e, 0x4f, 0x0e, 0x6a, 0x2b, 0xf5, 0xad, 0x97, 0xd7, 0xcd, 0x8f, 0x54, 0x8c, 0x05, 0x60, 0x40,
5588
-	0x99, 0xe7, 0xb3, 0x11, 0xda, 0x01, 0xab, 0xb3, 0xbf, 0xdf, 0x1f, 0x9c, 0xf5, 0x7b, 0xb5, 0x42,
5589
-	0xbd, 0xfe, 0xf2, 0xba, 0xf9, 0xf1, 0x32, 0xb0, 0xe3, 0xba, 0x34, 0x94, 0xd4, 0xab, 0x17, 0xbf,
5590
-	0xfd, 0x5b, 0x63, 0xa5, 0xf5, 0x6d, 0x01, 0xaa, 0xd9, 0x24, 0xd0, 0x23, 0x28, 0x75, 0xf6, 0xcf,
5591
-	0x0e, 0x9f, 0xf7, 0x6b, 0x2b, 0x0b, 0x7a, 0x16, 0xd1, 0x71, 0xa5, 0x7f, 0x45, 0xd1, 0x43, 0x58,
5592
-	0x1f, 0x74, 0xbe, 0x3e, 0xed, 0xd7, 0x0a, 0x8b, 0x74, 0xb2, 0xb0, 0x01, 0x89, 0x23, 0x8d, 0xea,
5593
-	0xe1, 0xce, 0xe1, 0x49, 0x6d, 0x35, 0x1f, 0xd5, 0x13, 0xc4, 0x67, 0x26, 0x95, 0xbf, 0x16, 0xc1,
5594
-	0x3e, 0xa5, 0xe2, 0xca, 0x77, 0x3f, 0xb0, 0x44, 0xbe, 0x80, 0xa2, 0x24, 0xd1, 0xa5, 0x96, 0x86,
5595
-	0x9d, 0x2f, 0x8d, 0x33, 0x12, 0x5d, 0xaa, 0x8f, 0x1a, 0xba, 0xc6, 0x2b, 0x65, 0x08, 0x1a, 0x06,
5596
-	0xbe, 0x4b, 0x24, 0xf5, 0xb4, 0x32, 0xec, 0xbd, 0x1f, 0xe6, 0xb1, 0xf1, 0x1c, 0x65, 0xf2, 0x7f,
5597
-	0xba, 0x82, 0x33, 0x54, 0xf4, 0x04, 0x4a, 0xa3, 0x80, 0x9f, 0x93, 0x40, 0x6b, 0xc2, 0xde, 0x7b,
5598
-	0x90, 0x17, 0xe4, 0x40, 0x23, 0x16, 0x01, 0x0c, 0x05, 0x3d, 0x86, 0x52, 0x1c, 0x7a, 0x44, 0x52,
5599
-	0xa7, 0xa4, 0xc9, 0xcd, 0x3c, 0xf2, 0xd7, 0x1a, 0xb1, 0xcf, 0xd9, 0x85, 0x3f, 0xc2, 0x06, 0x8f,
5600
-	0x8e, 0xc0, 0x62, 0x54, 0x7e, 0xc3, 0xc5, 0x65, 0xe4, 0x94, 0x9b, 0x6b, 0x3b, 0xf6, 0xde, 0xe7,
5601
-	0xb9, 0x62, 0x4c, 0x30, 0x1d, 0x29, 0x89, 0x3b, 0x9e, 0x50, 0x26, 0x93, 0x30, 0xdd, 0x55, 0xa7,
5602
-	0x80, 0xe7, 0x01, 0xd0, 0xaf, 0xc0, 0xa2, 0xcc, 0x0b, 0xb9, 0xcf, 0xa4, 0x63, 0xdd, 0x9e, 0x48,
5603
-	0xdf, 0x60, 0x54, 0x31, 0xf1, 0x9c, 0xa1, 0xd8, 0x82, 0x07, 0xc1, 0x39, 0x71, 0x2f, 0x9d, 0xca,
5604
-	0x7b, 0x2e, 0x63, 0xce, 0xe8, 0x96, 0xa0, 0x38, 0xe1, 0x1e, 0x6d, 0xed, 0xc2, 0xe6, 0x1b, 0xa5,
5605
-	0x46, 0x75, 0xb0, 0x4c, 0xa9, 0x13, 0x8d, 0x14, 0xf1, 0xdc, 0x6e, 0xdd, 0x85, 0x8d, 0xa5, 0xb2,
5606
-	0xb6, 0xfe, 0x59, 0x04, 0x2b, 0xdd, 0x6b, 0xd4, 0x81, 0x8a, 0xcb, 0x99, 0x24, 0x3e, 0xa3, 0xc2,
5607
-	0xc8, 0x2b, 0x77, 0x67, 0xf6, 0x53, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, 0x2d, 0x54,
5608
-	0x04, 0x8d, 0x78, 0x2c, 0x5c, 0x1a, 0x19, 0x7d, 0xed, 0xe4, 0x2b, 0x24, 0x01, 0x61, 0xfa, 0xa7,
5609
-	0xd8, 0x17, 0x54, 0x55, 0x39, 0xc2, 0x0b, 0x2a, 0x7a, 0x02, 0x65, 0x41, 0x23, 0x49, 0x84, 0x7c,
5610
-	0x9b, 0x44, 0x70, 0x02, 0x19, 0xf0, 0xc0, 0x77, 0xa7, 0x38, 0x65, 0xa0, 0x27, 0x50, 0x09, 0x03,
5611
-	0xe2, 0xea, 0xa8, 0xce, 0xba, 0xa6, 0x7f, 0x92, 0x47, 0x1f, 0xa4, 0x20, 0xbc, 0xc0, 0xa3, 0x2f,
5612
-	0x01, 0x02, 0x3e, 0x1a, 0x7a, 0xc2, 0xbf, 0xa2, 0xc2, 0x48, 0xac, 0x9e, 0xc7, 0xee, 0x69, 0x04,
5613
-	0xae, 0x04, 0x7c, 0x94, 0x0c, 0xd1, 0xc1, 0xff, 0xa5, 0xaf, 0x8c, 0xb6, 0x8e, 0x00, 0xc8, 0x7c,
5614
-	0xd6, 0xa8, 0xeb, 0xb3, 0xf7, 0x0a, 0x65, 0x76, 0x24, 0x43, 0x47, 0x0f, 0xa0, 0x7a, 0xc1, 0x85,
5615
-	0x4b, 0x87, 0xe6, 0xd4, 0x54, 0xb4, 0x26, 0x6c, 0xed, 0x4b, 0xf4, 0x85, 0xba, 0x50, 0x1e, 0x51,
5616
-	0x46, 0x85, 0xef, 0x3a, 0xa0, 0x3f, 0xf6, 0x28, 0xf7, 0x40, 0x26, 0x10, 0x1c, 0x33, 0xe9, 0x4f,
5617
-	0xa8, 0xf9, 0x52, 0x4a, 0xec, 0x56, 0xa0, 0x2c, 0x92, 0x99, 0xd6, 0x1f, 0x01, 0xbd, 0x89, 0x45,
5618
-	0x08, 0x8a, 0x97, 0x3e, 0xf3, 0xb4, 0xb0, 0x2a, 0x58, 0x8f, 0x51, 0x1b, 0xca, 0x21, 0x99, 0x06,
5619
-	0x9c, 0x78, 0x46, 0x2c, 0xf7, 0xda, 0x49, 0xbf, 0x6c, 0xa7, 0xfd, 0xb2, 0xdd, 0x61, 0x53, 0x9c,
5620
-	0x82, 0x5a, 0x47, 0xf0, 0x51, 0xee, 0x92, 0xd1, 0x1e, 0x54, 0xe7, 0x22, 0x1c, 0xfa, 0xe6, 0x23,
5621
-	0xdd, 0xbb, 0xb3, 0x9b, 0x6d, 0x7b, 0xae, 0xd6, 0xc3, 0x1e, 0xb6, 0xe7, 0xa0, 0x43, 0xaf, 0xf5,
5622
-	0x17, 0x0b, 0x36, 0x96, 0xa4, 0x8c, 0xee, 0xc1, 0xba, 0x3f, 0x21, 0x23, 0x6a, 0x72, 0x4c, 0x0c,
5623
-	0xd4, 0x87, 0x52, 0x40, 0xce, 0x69, 0xa0, 0x04, 0xad, 0x36, 0xf5, 0x27, 0xef, 0x3c, 0x13, 0xed,
5624
-	0xdf, 0x6b, 0x7c, 0x9f, 0x49, 0x31, 0xc5, 0x86, 0x8c, 0x1c, 0x28, 0xbb, 0x7c, 0x32, 0x21, 0x4c,
5625
-	0x5d, 0x9d, 0x6b, 0x3b, 0x15, 0x9c, 0x9a, 0xaa, 0x32, 0x44, 0x8c, 0x22, 0xa7, 0xa8, 0xdd, 0x7a,
5626
-	0x8c, 0x6a, 0xb0, 0x46, 0xd9, 0x95, 0xb3, 0xae, 0x5d, 0x6a, 0xa8, 0x3c, 0x9e, 0x9f, 0x28, 0xb2,
5627
-	0x82, 0xd5, 0x50, 0xf1, 0xe2, 0x88, 0x0a, 0xa7, 0x9c, 0x54, 0x54, 0x8d, 0xd1, 0x2f, 0xa0, 0x34,
5628
-	0xe1, 0x31, 0x93, 0x91, 0x63, 0xe9, 0x64, 0xb7, 0xf2, 0x92, 0x3d, 0x56, 0x08, 0x73, 0xb5, 0x1b,
5629
-	0x38, 0xea, 0xc3, 0x66, 0x24, 0x79, 0x38, 0x1c, 0x09, 0xe2, 0xd2, 0x61, 0x48, 0x85, 0xcf, 0x3d,
5630
-	0x73, 0x35, 0x6d, 0xbd, 0xb1, 0x29, 0x3d, 0xf3, 0xc8, 0xc1, 0x77, 0x15, 0xe7, 0x40, 0x51, 0x06,
5631
-	0x9a, 0x81, 0x06, 0x50, 0x0d, 0xe3, 0x20, 0x18, 0xf2, 0x30, 0xe9, 0x52, 0x89, 0x9e, 0xde, 0xa3,
5632
-	0x64, 0x83, 0x38, 0x08, 0x9e, 0x25, 0x24, 0x6c, 0x87, 0x0b, 0x03, 0x7d, 0x0c, 0xa5, 0x91, 0xe0,
5633
-	0x71, 0x18, 0x39, 0xb6, 0x2e, 0x86, 0xb1, 0xd0, 0x57, 0x50, 0x8e, 0xa8, 0x2b, 0xa8, 0x8c, 0x9c,
5634
-	0xaa, 0x5e, 0xea, 0xa7, 0x79, 0x1f, 0x39, 0xd5, 0x10, 0x4c, 0x2f, 0xa8, 0xa0, 0xcc, 0xa5, 0x38,
5635
-	0xe5, 0xa0, 0x2d, 0x58, 0x93, 0x72, 0xea, 0x6c, 0x34, 0x0b, 0x3b, 0x56, 0xb7, 0x3c, 0xbb, 0xd9,
5636
-	0x5e, 0x3b, 0x3b, 0x7b, 0x81, 0x95, 0x4f, 0xdd, 0xa0, 0x63, 0x1e, 0x49, 0x46, 0x26, 0xd4, 0xb9,
5637
-	0xa3, 0x6b, 0x3b, 0xb7, 0xd1, 0x0b, 0x00, 0x8f, 0x45, 0x43, 0x57, 0x1f, 0x59, 0xe7, 0xae, 0x5e,
5638
-	0xdd, 0xe7, 0xef, 0x5e, 0x5d, 0xef, 0xe4, 0xd4, 0x74, 0x91, 0x8d, 0xd9, 0xcd, 0x76, 0x65, 0x6e,
5639
-	0xe2, 0x8a, 0xc7, 0xa2, 0x64, 0x88, 0xba, 0x60, 0x8f, 0x29, 0x09, 0xe4, 0xd8, 0x1d, 0x53, 0xf7,
5640
-	0xd2, 0xa9, 0xdd, 0xde, 0x16, 0x9e, 0x6a, 0x98, 0x89, 0x90, 0x25, 0x29, 0x05, 0xab, 0x54, 0x23,
5641
-	0x67, 0x53, 0xd7, 0x2a, 0x31, 0xd0, 0x27, 0x00, 0x3c, 0xa4, 0x6c, 0x18, 0x49, 0xcf, 0x67, 0x0e,
5642
-	0x52, 0x4b, 0xc6, 0x15, 0xe5, 0x39, 0x55, 0x0e, 0x74, 0x5f, 0x5d, 0xda, 0xc4, 0x1b, 0x72, 0x16,
5643
-	0x4c, 0x9d, 0xef, 0xe9, 0x59, 0x4b, 0x39, 0x9e, 0xb1, 0x60, 0x8a, 0xb6, 0xc1, 0xd6, 0xba, 0x88,
5644
-	0xfc, 0x11, 0x23, 0x81, 0x73, 0x4f, 0xd7, 0x03, 0x94, 0xeb, 0x54, 0x7b, 0xea, 0x5f, 0x82, 0x9d,
5645
-	0x91, 0xbb, 0x92, 0xe9, 0x25, 0x9d, 0x9a, 0x13, 0xa4, 0x86, 0x2a, 0xa7, 0x2b, 0x12, 0xc4, 0xc9,
5646
-	0x53, 0xb4, 0x82, 0x13, 0xe3, 0x97, 0xab, 0x8f, 0x0b, 0xf5, 0x3d, 0xb0, 0x33, 0xdb, 0x8e, 0x3e,
5647
-	0x85, 0x0d, 0x41, 0x47, 0x7e, 0x24, 0xc5, 0x74, 0x48, 0x62, 0x39, 0x76, 0x7e, 0xa3, 0x09, 0xd5,
5648
-	0xd4, 0xd9, 0x89, 0xe5, 0xb8, 0x3e, 0x84, 0x45, 0xf5, 0x50, 0x13, 0x6c, 0xb5, 0x2b, 0x11, 0x15,
5649
-	0x57, 0x54, 0xa8, 0x76, 0xa7, 0x16, 0x9d, 0x75, 0x29, 0xf5, 0x44, 0x94, 0x08, 0x77, 0xac, 0x0f,
5650
-	0x6f, 0x05, 0x1b, 0x4b, 0x9d, 0xc6, 0x54, 0xa2, 0xe6, 0x34, 0x1a, 0xb3, 0xf5, 0x9f, 0x02, 0x54,
5651
-	0xb3, 0x5d, 0x1b, 0xed, 0x27, 0xdd, 0x56, 0x2f, 0xe9, 0xce, 0xde, 0xee, 0xbb, 0xba, 0xbc, 0xee,
5652
-	0x6d, 0x41, 0xac, 0x82, 0x1d, 0xab, 0x07, 0xb6, 0x26, 0xa3, 0x9f, 0xc3, 0x7a, 0xc8, 0x85, 0x4c,
5653
-	0xef, 0x90, 0x46, 0x6e, 0x3f, 0xe2, 0x22, 0xed, 0x05, 0x09, 0xb8, 0x35, 0x86, 0x3b, 0xcb, 0xd1,
5654
-	0xd0, 0x43, 0x58, 0x7b, 0x7e, 0x38, 0xa8, 0xad, 0xd4, 0xef, 0xbf, 0xbc, 0x6e, 0x7e, 0x7f, 0x79,
5655
-	0xf2, 0xb9, 0x2f, 0x64, 0x4c, 0x82, 0xc3, 0x01, 0xfa, 0x31, 0xac, 0xf7, 0x4e, 0x4e, 0x31, 0xae,
5656
-	0x15, 0xea, 0xdb, 0x2f, 0xaf, 0x9b, 0xf7, 0x97, 0x71, 0x6a, 0x8a, 0xc7, 0xcc, 0xc3, 0xfc, 0x7c,
5657
-	0xfe, 0xd8, 0xfc, 0xfb, 0x2a, 0xd8, 0xe6, 0x6a, 0xfd, 0xd0, 0xff, 0x23, 0x1b, 0x49, 0x2f, 0x4d,
5658
-	0xcf, 0xcc, 0xea, 0x3b, 0x5b, 0x6a, 0x35, 0x21, 0x98, 0x3d, 0x7e, 0x00, 0x55, 0x3f, 0xbc, 0xfa,
5659
-	0x62, 0x48, 0x19, 0x39, 0x0f, 0xcc, 0xbb, 0xd3, 0xc2, 0xb6, 0xf2, 0xf5, 0x13, 0x97, 0x3a, 0xb0,
5660
-	0x3e, 0x93, 0x54, 0x30, 0xf3, 0xa2, 0xb4, 0xf0, 0xdc, 0x46, 0x5f, 0x41, 0xd1, 0x0f, 0xc9, 0xc4,
5661
-	0xbc, 0x03, 0x72, 0x57, 0x70, 0x38, 0xe8, 0x1c, 0x1b, 0x0d, 0x76, 0xad, 0xd9, 0xcd, 0x76, 0x51,
5662
-	0x39, 0xb0, 0xa6, 0xa1, 0x46, 0xda, 0x8a, 0xd5, 0x97, 0xf4, 0xe5, 0x6b, 0xe1, 0x8c, 0x47, 0xe9,
5663
-	0xc8, 0x67, 0x23, 0x41, 0xa3, 0x48, 0x5f, 0xc3, 0x16, 0x4e, 0xcd, 0xd6, 0x7f, 0x8b, 0x60, 0xef,
5664
-	0x07, 0x71, 0x24, 0x4d, 0x73, 0xf9, 0x60, 0x15, 0x7d, 0x01, 0x9b, 0x44, 0xff, 0xb4, 0x10, 0xa6,
5665
-	0x6e, 0x6a, 0xfd, 0xf8, 0x31, 0x55, 0x7d, 0x98, 0x1b, 0x6e, 0x0e, 0x4e, 0x1e, 0x4a, 0xdd, 0x92,
5666
-	0x8a, 0xe9, 0x14, 0x70, 0x8d, 0xbc, 0x36, 0x83, 0x4e, 0x61, 0x83, 0x0b, 0x77, 0x4c, 0x23, 0x99,
5667
-	0xdc, 0xef, 0xe6, 0x91, 0x9f, 0xfb, 0xfb, 0xf7, 0x2c, 0x0b, 0x34, 0x97, 0x5b, 0x92, 0xed, 0x72,
5668
-	0x0c, 0xf4, 0x18, 0x8a, 0x82, 0x5c, 0xa4, 0x0f, 0xb9, 0x5c, 0xe5, 0x63, 0x72, 0x21, 0x97, 0x42,
5669
-	0x68, 0x06, 0xfa, 0x1d, 0x80, 0xe7, 0x47, 0x21, 0x91, 0xee, 0x98, 0x0a, 0xb3, 0x83, 0xb9, 0x4b,
5670
-	0xec, 0xcd, 0x51, 0x4b, 0x51, 0x32, 0x6c, 0x74, 0x04, 0x15, 0x97, 0xa4, 0x1a, 0x2c, 0xdd, 0xfe,
5671
-	0xe7, 0xb3, 0xdf, 0x31, 0x21, 0x6a, 0x2a, 0xc4, 0xec, 0x66, 0xdb, 0x4a, 0x3d, 0xd8, 0x72, 0x89,
5672
-	0xd1, 0xe4, 0x11, 0x6c, 0xa8, 0x3f, 0xa2, 0xa1, 0x47, 0x2f, 0x48, 0x1c, 0xc8, 0x64, 0xef, 0x6f,
5673
-	0xb9, 0xac, 0xd5, 0xf3, 0xba, 0x67, 0x70, 0x26, 0xaf, 0xaa, 0xcc, 0xf8, 0xd0, 0x1f, 0x60, 0x93,
5674
-	0x32, 0x57, 0x4c, 0xb5, 0x02, 0xd3, 0x0c, 0xad, 0xdb, 0x17, 0xdb, 0x9f, 0x83, 0x97, 0x16, 0x5b,
5675
-	0xa3, 0xaf, 0xf9, 0x5b, 0x3e, 0x40, 0xd2, 0xfe, 0x3e, 0xac, 0xfe, 0x10, 0x14, 0x3d, 0x22, 0x89,
5676
-	0x96, 0x5c, 0x15, 0xeb, 0x71, 0xd7, 0x79, 0xf5, 0x5d, 0x63, 0xe5, 0x5f, 0xdf, 0x35, 0x56, 0xfe,
5677
-	0x3c, 0x6b, 0x14, 0x5e, 0xcd, 0x1a, 0x85, 0x7f, 0xcc, 0x1a, 0x85, 0x7f, 0xcf, 0x1a, 0x85, 0xf3,
5678
-	0x92, 0x7e, 0x34, 0xfc, 0xec, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x3e, 0xe8, 0xcb, 0x6d,
5679
-	0x11, 0x00, 0x00,
5567
+	// 1824 bytes of a gzipped FileDescriptorProto
5568
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0x4f, 0x73, 0x1b, 0x49,
5569
+	0x15, 0xb7, 0x6c, 0x59, 0x7f, 0xde, 0xc8, 0x89, 0xd2, 0x24, 0x61, 0xac, 0xb0, 0xb2, 0xa2, 0x0d,
5570
+	0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0x4b, 0x58, 0x40, 0xb2, 0x84, 0x63, 0x8c, 0x1d, 0x55,
5571
+	0xdb, 0x1b, 0xc8, 0x49, 0xd5, 0x9e, 0x69, 0x4b, 0x53, 0x1e, 0x75, 0x0f, 0xdd, 0x3d, 0xda, 0xd2,
5572
+	0x8d, 0xe3, 0x56, 0xae, 0x9c, 0x5d, 0x1c, 0xf8, 0x32, 0xb9, 0x41, 0x71, 0xe2, 0xe4, 0x62, 0xfd,
5573
+	0x15, 0xf8, 0x00, 0x50, 0xdd, 0xd3, 0xa3, 0x3f, 0xc9, 0x78, 0x93, 0x2a, 0xc2, 0xad, 0xfb, 0xcd,
5574
+	0xef, 0xf7, 0xfa, 0xf5, 0xeb, 0x5f, 0xf7, 0x7b, 0x03, 0x8e, 0x8c, 0xa8, 0x27, 0x5b, 0x91, 0xe0,
5575
+	0x8a, 0x23, 0xe4, 0x73, 0xef, 0x82, 0x8a, 0x96, 0xfc, 0x8a, 0x88, 0xf1, 0x45, 0xa0, 0x5a, 0x93,
5576
+	0x1f, 0xd7, 0x1c, 0x35, 0x8d, 0xa8, 0x05, 0xd4, 0xee, 0x0e, 0xf9, 0x90, 0x9b, 0xe1, 0x8e, 0x1e,
5577
+	0x59, 0x6b, 0x7d, 0xc8, 0xf9, 0x30, 0xa4, 0x3b, 0x66, 0x76, 0x16, 0x9f, 0xef, 0xf8, 0xb1, 0x20,
5578
+	0x2a, 0xe0, 0xcc, 0x7e, 0xdf, 0x7c, 0xf3, 0x3b, 0x61, 0xd3, 0xe4, 0x53, 0xf3, 0x32, 0x0f, 0xa5,
5579
+	0x63, 0xee, 0xd3, 0x93, 0x88, 0x7a, 0x68, 0x1f, 0x1c, 0xc2, 0x18, 0x57, 0x86, 0x2b, 0xdd, 0x5c,
5580
+	0x23, 0xb7, 0xed, 0xec, 0x6e, 0xb5, 0xde, 0x0e, 0xaa, 0xd5, 0x9e, 0xc3, 0x3a, 0xf9, 0xd7, 0x57,
5581
+	0x5b, 0x2b, 0x78, 0x91, 0x89, 0x7e, 0x05, 0x15, 0x9f, 0xca, 0x40, 0x50, 0x7f, 0x20, 0x78, 0x48,
5582
+	0xdd, 0xd5, 0x46, 0x6e, 0xfb, 0xd6, 0xee, 0xf7, 0xb2, 0x3c, 0xe9, 0xc5, 0x31, 0x0f, 0x29, 0x76,
5583
+	0x2c, 0x43, 0x4f, 0xd0, 0x3e, 0xc0, 0x98, 0x8e, 0xcf, 0xa8, 0x90, 0xa3, 0x20, 0x72, 0xd7, 0x0c,
5584
+	0xfd, 0x07, 0x37, 0xd1, 0x75, 0xec, 0xad, 0xa3, 0x19, 0x1c, 0x2f, 0x50, 0xd1, 0x11, 0x54, 0xc8,
5585
+	0x84, 0x04, 0x21, 0x39, 0x0b, 0xc2, 0x40, 0x4d, 0xdd, 0xbc, 0x71, 0xf5, 0xc9, 0xb7, 0xba, 0x6a,
5586
+	0x2f, 0x10, 0xf0, 0x12, 0xbd, 0xe9, 0x03, 0xcc, 0x17, 0x42, 0x8f, 0xa1, 0xd8, 0xef, 0x1d, 0x77,
5587
+	0x0f, 0x8e, 0xf7, 0xab, 0x2b, 0xb5, 0xcd, 0x57, 0x97, 0x8d, 0x7b, 0xda, 0xc7, 0x1c, 0xd0, 0xa7,
5588
+	0xcc, 0x0f, 0xd8, 0x10, 0x6d, 0x43, 0xa9, 0xbd, 0xb7, 0xd7, 0xeb, 0x9f, 0xf6, 0xba, 0xd5, 0x5c,
5589
+	0xad, 0xf6, 0xea, 0xb2, 0x71, 0x7f, 0x19, 0xd8, 0xf6, 0x3c, 0x1a, 0x29, 0xea, 0xd7, 0xf2, 0x5f,
5590
+	0xff, 0xb5, 0xbe, 0xd2, 0xfc, 0x3a, 0x07, 0x95, 0xc5, 0x20, 0xd0, 0x63, 0x28, 0xb4, 0xf7, 0x4e,
5591
+	0x0f, 0x5e, 0xf4, 0xaa, 0x2b, 0x73, 0xfa, 0x22, 0xa2, 0xed, 0xa9, 0x60, 0x42, 0xd1, 0x23, 0x58,
5592
+	0xef, 0xb7, 0xbf, 0x3c, 0xe9, 0x55, 0x73, 0xf3, 0x70, 0x16, 0x61, 0x7d, 0x12, 0x4b, 0x83, 0xea,
5593
+	0xe2, 0xf6, 0xc1, 0x71, 0x75, 0x35, 0x1b, 0xd5, 0x15, 0x24, 0x60, 0x36, 0x94, 0xbf, 0xe4, 0xc1,
5594
+	0x39, 0xa1, 0x62, 0x12, 0x78, 0x1f, 0x58, 0x22, 0x9f, 0x41, 0x5e, 0x11, 0x79, 0x61, 0xa4, 0xe1,
5595
+	0x64, 0x4b, 0xe3, 0x94, 0xc8, 0x0b, 0xbd, 0xa8, 0xa5, 0x1b, 0xbc, 0x56, 0x86, 0xa0, 0x51, 0x18,
5596
+	0x78, 0x44, 0x51, 0xdf, 0x28, 0xc3, 0xd9, 0xfd, 0x7e, 0x16, 0x1b, 0xcf, 0x50, 0x36, 0xfe, 0x67,
5597
+	0x2b, 0x78, 0x81, 0x8a, 0x9e, 0x42, 0x61, 0x18, 0xf2, 0x33, 0x12, 0x1a, 0x4d, 0x38, 0xbb, 0x0f,
5598
+	0xb3, 0x9c, 0xec, 0x1b, 0xc4, 0xdc, 0x81, 0xa5, 0xa0, 0x27, 0x50, 0x88, 0x23, 0x9f, 0x28, 0xea,
5599
+	0x16, 0x0c, 0xb9, 0x91, 0x45, 0xfe, 0xd2, 0x20, 0xf6, 0x38, 0x3b, 0x0f, 0x86, 0xd8, 0xe2, 0xd1,
5600
+	0x21, 0x94, 0x18, 0x55, 0x5f, 0x71, 0x71, 0x21, 0xdd, 0x62, 0x63, 0x6d, 0xdb, 0xd9, 0xfd, 0x34,
5601
+	0x53, 0x8c, 0x09, 0xa6, 0xad, 0x14, 0xf1, 0x46, 0x63, 0xca, 0x54, 0xe2, 0xa6, 0xb3, 0xea, 0xe6,
5602
+	0xf0, 0xcc, 0x01, 0xfa, 0x05, 0x94, 0x28, 0xf3, 0x23, 0x1e, 0x30, 0xe5, 0x96, 0x6e, 0x0e, 0xa4,
5603
+	0x67, 0x31, 0x3a, 0x99, 0x78, 0xc6, 0xd0, 0x6c, 0xc1, 0xc3, 0xf0, 0x8c, 0x78, 0x17, 0x6e, 0xf9,
5604
+	0x3d, 0xb7, 0x31, 0x63, 0x74, 0x0a, 0x90, 0x1f, 0x73, 0x9f, 0x36, 0x77, 0xe0, 0xce, 0x5b, 0xa9,
5605
+	0x46, 0x35, 0x28, 0xd9, 0x54, 0x27, 0x1a, 0xc9, 0xe3, 0xd9, 0xbc, 0x79, 0x1b, 0x36, 0x96, 0xd2,
5606
+	0xda, 0xfc, 0x47, 0x1e, 0x4a, 0xe9, 0x59, 0xa3, 0x36, 0x94, 0x3d, 0xce, 0x14, 0x09, 0x18, 0x15,
5607
+	0x56, 0x5e, 0x99, 0x27, 0xb3, 0x97, 0x82, 0x34, 0xeb, 0xd9, 0x0a, 0x9e, 0xb3, 0xd0, 0x6f, 0xa0,
5608
+	0x2c, 0xa8, 0xe4, 0xb1, 0xf0, 0xa8, 0xb4, 0xfa, 0xda, 0xce, 0x56, 0x48, 0x02, 0xc2, 0xf4, 0x8f,
5609
+	0x71, 0x20, 0xa8, 0xce, 0xb2, 0xc4, 0x73, 0x2a, 0x7a, 0x0a, 0x45, 0x41, 0xa5, 0x22, 0x42, 0x7d,
5610
+	0x9b, 0x44, 0x70, 0x02, 0xe9, 0xf3, 0x30, 0xf0, 0xa6, 0x38, 0x65, 0xa0, 0xa7, 0x50, 0x8e, 0x42,
5611
+	0xe2, 0x19, 0xaf, 0xee, 0xba, 0xa1, 0x7f, 0x94, 0x45, 0xef, 0xa7, 0x20, 0x3c, 0xc7, 0xa3, 0xcf,
5612
+	0x01, 0x42, 0x3e, 0x1c, 0xf8, 0x22, 0x98, 0x50, 0x61, 0x25, 0x56, 0xcb, 0x62, 0x77, 0x0d, 0x02,
5613
+	0x97, 0x43, 0x3e, 0x4c, 0x86, 0x68, 0xff, 0x7f, 0xd2, 0xd7, 0x82, 0xb6, 0x0e, 0x01, 0xc8, 0xec,
5614
+	0xab, 0x55, 0xd7, 0x27, 0xef, 0xe5, 0xca, 0x9e, 0xc8, 0x02, 0x1d, 0x3d, 0x84, 0xca, 0x39, 0x17,
5615
+	0x1e, 0x1d, 0xd8, 0x5b, 0x53, 0x36, 0x9a, 0x70, 0x8c, 0x2d, 0xd1, 0x17, 0xea, 0x40, 0x71, 0x48,
5616
+	0x19, 0x15, 0x81, 0xe7, 0x82, 0x59, 0xec, 0x71, 0xe6, 0x85, 0x4c, 0x20, 0x38, 0x66, 0x2a, 0x18,
5617
+	0x53, 0xbb, 0x52, 0x4a, 0xec, 0x94, 0xa1, 0x28, 0x92, 0x2f, 0xcd, 0x3f, 0x00, 0x7a, 0x1b, 0x8b,
5618
+	0x10, 0xe4, 0x2f, 0x02, 0xe6, 0x1b, 0x61, 0x95, 0xb1, 0x19, 0xa3, 0x16, 0x14, 0x23, 0x32, 0x0d,
5619
+	0x39, 0xf1, 0xad, 0x58, 0xee, 0xb6, 0x92, 0x7a, 0xd9, 0x4a, 0xeb, 0x65, 0xab, 0xcd, 0xa6, 0x38,
5620
+	0x05, 0x35, 0x0f, 0xe1, 0x5e, 0xe6, 0x96, 0xd1, 0x2e, 0x54, 0x66, 0x22, 0x1c, 0x04, 0x76, 0x91,
5621
+	0xce, 0xed, 0xeb, 0xab, 0x2d, 0x67, 0xa6, 0xd6, 0x83, 0x2e, 0x76, 0x66, 0xa0, 0x03, 0xbf, 0xf9,
5622
+	0xe7, 0x32, 0x6c, 0x2c, 0x49, 0x19, 0xdd, 0x85, 0xf5, 0x60, 0x4c, 0x86, 0xd4, 0xc6, 0x98, 0x4c,
5623
+	0x50, 0x0f, 0x0a, 0x21, 0x39, 0xa3, 0xa1, 0x16, 0xb4, 0x3e, 0xd4, 0x1f, 0xbd, 0xf3, 0x4e, 0xb4,
5624
+	0x7e, 0x67, 0xf0, 0x3d, 0xa6, 0xc4, 0x14, 0x5b, 0x32, 0x72, 0xa1, 0xe8, 0xf1, 0xf1, 0x98, 0x30,
5625
+	0xfd, 0x74, 0xae, 0x6d, 0x97, 0x71, 0x3a, 0xd5, 0x99, 0x21, 0x62, 0x28, 0xdd, 0xbc, 0x31, 0x9b,
5626
+	0x31, 0xaa, 0xc2, 0x1a, 0x65, 0x13, 0x77, 0xdd, 0x98, 0xf4, 0x50, 0x5b, 0xfc, 0x20, 0x51, 0x64,
5627
+	0x19, 0xeb, 0xa1, 0xe6, 0xc5, 0x92, 0x0a, 0xb7, 0x98, 0x64, 0x54, 0x8f, 0xd1, 0xcf, 0xa0, 0x30,
5628
+	0xe6, 0x31, 0x53, 0xd2, 0x2d, 0x99, 0x60, 0x37, 0xb3, 0x82, 0x3d, 0xd2, 0x08, 0xfb, 0xb4, 0x5b,
5629
+	0x38, 0xea, 0xc1, 0x1d, 0xa9, 0x78, 0x34, 0x18, 0x0a, 0xe2, 0xd1, 0x41, 0x44, 0x45, 0xc0, 0x7d,
5630
+	0xfb, 0x34, 0x6d, 0xbe, 0x75, 0x28, 0x5d, 0xdb, 0xe4, 0xe0, 0xdb, 0x9a, 0xb3, 0xaf, 0x29, 0x7d,
5631
+	0xc3, 0x40, 0x7d, 0xa8, 0x44, 0x71, 0x18, 0x0e, 0x78, 0x94, 0x54, 0xa9, 0x44, 0x4f, 0xef, 0x91,
5632
+	0xb2, 0x7e, 0x1c, 0x86, 0xcf, 0x13, 0x12, 0x76, 0xa2, 0xf9, 0x04, 0xdd, 0x87, 0xc2, 0x50, 0xf0,
5633
+	0x38, 0x92, 0xae, 0x63, 0x92, 0x61, 0x67, 0xe8, 0x0b, 0x28, 0x4a, 0xea, 0x09, 0xaa, 0xa4, 0x5b,
5634
+	0x31, 0x5b, 0xfd, 0x38, 0x6b, 0x91, 0x13, 0x03, 0xc1, 0xf4, 0x9c, 0x0a, 0xca, 0x3c, 0x8a, 0x53,
5635
+	0x0e, 0xda, 0x84, 0x35, 0xa5, 0xa6, 0xee, 0x46, 0x23, 0xb7, 0x5d, 0xea, 0x14, 0xaf, 0xaf, 0xb6,
5636
+	0xd6, 0x4e, 0x4f, 0x5f, 0x62, 0x6d, 0xd3, 0x2f, 0xe8, 0x88, 0x4b, 0xc5, 0xc8, 0x98, 0xba, 0xb7,
5637
+	0x4c, 0x6e, 0x67, 0x73, 0xf4, 0x12, 0xc0, 0x67, 0x72, 0xe0, 0x99, 0x2b, 0xeb, 0xde, 0x36, 0xbb,
5638
+	0xfb, 0xf4, 0xdd, 0xbb, 0xeb, 0x1e, 0x9f, 0xd8, 0x2a, 0xb2, 0x71, 0x7d, 0xb5, 0x55, 0x9e, 0x4d,
5639
+	0x71, 0xd9, 0x67, 0x32, 0x19, 0xa2, 0x0e, 0x38, 0x23, 0x4a, 0x42, 0x35, 0xf2, 0x46, 0xd4, 0xbb,
5640
+	0x70, 0xab, 0x37, 0x97, 0x85, 0x67, 0x06, 0x66, 0x3d, 0x2c, 0x92, 0xb4, 0x82, 0x75, 0xa8, 0xd2,
5641
+	0xbd, 0x63, 0x72, 0x95, 0x4c, 0xd0, 0x47, 0x00, 0x3c, 0xa2, 0x6c, 0x20, 0x95, 0x1f, 0x30, 0x17,
5642
+	0xe9, 0x2d, 0xe3, 0xb2, 0xb6, 0x9c, 0x68, 0x03, 0x7a, 0xa0, 0x1f, 0x6d, 0xe2, 0x0f, 0x38, 0x0b,
5643
+	0xa7, 0xee, 0x77, 0xcc, 0xd7, 0x92, 0x36, 0x3c, 0x67, 0xe1, 0x14, 0x6d, 0x81, 0x63, 0x74, 0x21,
5644
+	0x83, 0x21, 0x23, 0xa1, 0x7b, 0xd7, 0xe4, 0x03, 0xb4, 0xe9, 0xc4, 0x58, 0xf4, 0x39, 0x24, 0xd9,
5645
+	0x90, 0xee, 0xbd, 0x9b, 0xcf, 0xc1, 0x06, 0x3b, 0x3f, 0x07, 0xcb, 0x41, 0xbf, 0x04, 0x88, 0x44,
5646
+	0x30, 0x09, 0x42, 0x3a, 0xa4, 0xd2, 0xbd, 0x6f, 0x36, 0x5d, 0xcf, 0x7c, 0xad, 0x67, 0x28, 0xbc,
5647
+	0xc0, 0xa8, 0x7d, 0x0e, 0xce, 0xc2, 0x6d, 0xd3, 0xb7, 0xe4, 0x82, 0x4e, 0xed, 0x05, 0xd6, 0x43,
5648
+	0x9d, 0x92, 0x09, 0x09, 0xe3, 0xa4, 0x13, 0x2e, 0xe3, 0x64, 0xf2, 0xf3, 0xd5, 0x27, 0xb9, 0xda,
5649
+	0x2e, 0x38, 0x0b, 0xaa, 0x43, 0x1f, 0xc3, 0x86, 0xa0, 0xc3, 0x40, 0x2a, 0x31, 0x1d, 0x90, 0x58,
5650
+	0x8d, 0xdc, 0x5f, 0x1b, 0x42, 0x25, 0x35, 0xb6, 0x63, 0x35, 0xaa, 0x0d, 0x60, 0x7e, 0x78, 0xa8,
5651
+	0x01, 0x8e, 0x16, 0x85, 0xa4, 0x62, 0x42, 0x85, 0xae, 0xb6, 0x3a, 0xe7, 0x8b, 0x26, 0x2d, 0x5e,
5652
+	0x49, 0x89, 0xf0, 0x46, 0xe6, 0xed, 0x28, 0x63, 0x3b, 0xd3, 0x8f, 0x41, 0x7a, 0x43, 0xec, 0x63,
5653
+	0x60, 0xa7, 0xcd, 0x7f, 0xe7, 0xa0, 0xb2, 0xd8, 0x34, 0xa0, 0xbd, 0xa4, 0xd8, 0x9b, 0x2d, 0xdd,
5654
+	0xda, 0xdd, 0x79, 0x57, 0x93, 0x61, 0x4a, 0x6b, 0x18, 0x6b, 0x67, 0x47, 0xba, 0xbf, 0x37, 0x64,
5655
+	0xf4, 0x53, 0x58, 0x8f, 0xb8, 0x50, 0xe9, 0x13, 0x96, 0x9d, 0x60, 0x2e, 0xd2, 0x52, 0x94, 0x80,
5656
+	0x9b, 0x23, 0xb8, 0xb5, 0xec, 0x0d, 0x3d, 0x82, 0xb5, 0x17, 0x07, 0xfd, 0xea, 0x4a, 0xed, 0xc1,
5657
+	0xab, 0xcb, 0xc6, 0x77, 0x97, 0x3f, 0xbe, 0x08, 0x84, 0x8a, 0x49, 0x78, 0xd0, 0x47, 0x3f, 0x84,
5658
+	0xf5, 0xee, 0xf1, 0x09, 0xc6, 0xd5, 0x5c, 0x6d, 0xeb, 0xd5, 0x65, 0xe3, 0xc1, 0x32, 0x4e, 0x7f,
5659
+	0xe2, 0x31, 0xf3, 0x31, 0x3f, 0x9b, 0xf5, 0xba, 0x7f, 0x5b, 0x05, 0xc7, 0xbe, 0xec, 0x1f, 0xfa,
5660
+	0x77, 0x68, 0x23, 0x29, 0xe5, 0xe9, 0x95, 0x5d, 0x7d, 0x67, 0x45, 0xaf, 0x24, 0x04, 0x7b, 0xc6,
5661
+	0x0f, 0xa1, 0x12, 0x44, 0x93, 0xcf, 0x06, 0x94, 0x91, 0xb3, 0xd0, 0xb6, 0xbd, 0x25, 0xec, 0x68,
5662
+	0x5b, 0x2f, 0x31, 0xe9, 0xf7, 0x22, 0x60, 0x8a, 0x0a, 0x66, 0x1b, 0xda, 0x12, 0x9e, 0xcd, 0xd1,
5663
+	0x17, 0x90, 0x0f, 0x22, 0x32, 0xb6, 0x6d, 0x48, 0xe6, 0x0e, 0x0e, 0xfa, 0xed, 0x23, 0xab, 0xc1,
5664
+	0x4e, 0xe9, 0xfa, 0x6a, 0x2b, 0xaf, 0x0d, 0xd8, 0xd0, 0x50, 0x3d, 0xed, 0x04, 0xf4, 0x4a, 0xe6,
5665
+	0xed, 0x2f, 0xe1, 0x05, 0x8b, 0xd6, 0x51, 0xc0, 0x86, 0x82, 0x4a, 0x69, 0xaa, 0x40, 0x09, 0xa7,
5666
+	0xd3, 0xe6, 0x7f, 0xf2, 0xe0, 0xec, 0x85, 0xb1, 0x54, 0xb6, 0xb6, 0x7d, 0xb0, 0x8c, 0xbe, 0x84,
5667
+	0x3b, 0xc4, 0xfc, 0x33, 0x11, 0xa6, 0x0b, 0x85, 0xe9, 0xbd, 0x6c, 0x56, 0x1f, 0x65, 0xba, 0x9b,
5668
+	0x81, 0x93, 0x3e, 0xad, 0x53, 0xd0, 0x3e, 0xdd, 0x1c, 0xae, 0x92, 0x37, 0xbe, 0xa0, 0x13, 0xd8,
5669
+	0xe0, 0xc2, 0x1b, 0x51, 0xa9, 0x92, 0xf2, 0x62, 0xff, 0x31, 0x32, 0xff, 0x3e, 0x9f, 0x2f, 0x02,
5670
+	0xed, 0xdb, 0x9a, 0x44, 0xbb, 0xec, 0x03, 0x3d, 0x81, 0xbc, 0x20, 0xe7, 0x69, 0x1f, 0x99, 0xa9,
5671
+	0x7c, 0x4c, 0xce, 0xd5, 0x92, 0x0b, 0xc3, 0x40, 0xbf, 0x05, 0xf0, 0x03, 0x19, 0x11, 0xe5, 0x8d,
5672
+	0xa8, 0xb0, 0x27, 0x98, 0xb9, 0xc5, 0xee, 0x0c, 0xb5, 0xe4, 0x65, 0x81, 0x8d, 0x0e, 0xa1, 0xec,
5673
+	0x91, 0x54, 0x83, 0x85, 0x9b, 0x7f, 0xbc, 0xf6, 0xda, 0xd6, 0x45, 0x55, 0xbb, 0xb8, 0xbe, 0xda,
5674
+	0x2a, 0xa5, 0x16, 0x5c, 0xf2, 0x88, 0xd5, 0xe4, 0x21, 0x6c, 0xe8, 0x1f, 0xb2, 0x81, 0x4f, 0xcf,
5675
+	0x49, 0x1c, 0xaa, 0xe4, 0xec, 0x6f, 0xa8, 0x15, 0xba, 0xbb, 0xef, 0x5a, 0x9c, 0x8d, 0xab, 0xa2,
5676
+	0x16, 0x6c, 0xe8, 0xf7, 0x70, 0x87, 0x32, 0x4f, 0x4c, 0x8d, 0x02, 0xd3, 0x08, 0x4b, 0x37, 0x6f,
5677
+	0xb6, 0x37, 0x03, 0x2f, 0x6d, 0xb6, 0x4a, 0xdf, 0xb0, 0x37, 0x03, 0x80, 0xa4, 0xfa, 0x7e, 0x58,
5678
+	0xfd, 0x21, 0xc8, 0xfb, 0x44, 0x11, 0x23, 0xb9, 0x0a, 0x36, 0x63, 0xbd, 0x54, 0xb2, 0xe8, 0xff,
5679
+	0x7d, 0xa9, 0x8e, 0xfb, 0xfa, 0x9b, 0xfa, 0xca, 0x3f, 0xbf, 0xa9, 0xaf, 0xfc, 0xe9, 0xba, 0x9e,
5680
+	0x7b, 0x7d, 0x5d, 0xcf, 0xfd, 0xfd, 0xba, 0x9e, 0xfb, 0xd7, 0x75, 0x3d, 0x77, 0x56, 0x30, 0xed,
5681
+	0xd1, 0x4f, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x90, 0x54, 0x3b, 0xfc, 0x57, 0x12, 0x00, 0x00,
5680 5682
 }
... ...
@@ -197,6 +197,9 @@ message ContainerSpec {
197 197
 	// Groups specifies supplementary groups available to the user.
198 198
 	repeated string groups = 11;
199 199
 
200
+	// Privileges specifies security configuration/permissions.
201
+	Privileges privileges = 22;
202
+
200 203
 	// TTY declares that a TTY should be attached to the standard streams,
201 204
 	// including stdin if it is still open.
202 205
 	bool tty = 13 [(gogoproto.customname) = "TTY"];
... ...
@@ -236,6 +239,10 @@ message ContainerSpec {
236 236
 	// will be exposed to the container.
237 237
 	repeated SecretReference secrets = 12;
238 238
 
239
+	// ConfigReference contains references to zero or more configs that
240
+	// will be exposed to the container.
241
+	repeated ConfigReference configs = 21;
242
+
239 243
 	// Hosts allow additional entries to be specified in /etc/hosts
240 244
 	// that associates IP addresses with hostnames.
241 245
 	// Detailed documentation is available in:
... ...
@@ -371,3 +378,13 @@ message SecretSpec {
371 371
 	// Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes)
372 372
 	bytes data = 2;
373 373
 }
374
+
375
+// ConfigSpec specifies user-provided configuration files.
376
+message ConfigSpec {
377
+	Annotations annotations = 1 [(gogoproto.nullable) = false];
378
+
379
+	// Data is the config payload - the maximum size is 500KB (that is, 500*1024 bytes)
380
+	// TODO(aaronl): Do we want to revise this to include multiple payloads in a single
381
+	// ConfigSpec? Define this to be a tar? etc...
382
+	bytes data = 2;
383
+}
... ...
@@ -73,6 +73,7 @@ type Object struct {
73 73
 	//	*Object_Secret
74 74
 	//	*Object_Resource
75 75
 	//	*Object_Extension
76
+	//	*Object_Config
76 77
 	Object isObject_Object `protobuf_oneof:"Object"`
77 78
 }
78 79
 
... ...
@@ -110,6 +111,9 @@ type Object_Resource struct {
110 110
 type Object_Extension struct {
111 111
 	Extension *Extension `protobuf:"bytes,8,opt,name=extension,oneof"`
112 112
 }
113
+type Object_Config struct {
114
+	Config *Config `protobuf:"bytes,9,opt,name=config,oneof"`
115
+}
113 116
 
114 117
 func (*Object_Node) isObject_Object()      {}
115 118
 func (*Object_Service) isObject_Object()   {}
... ...
@@ -119,6 +123,7 @@ func (*Object_Cluster) isObject_Object()   {}
119 119
 func (*Object_Secret) isObject_Object()    {}
120 120
 func (*Object_Resource) isObject_Object()  {}
121 121
 func (*Object_Extension) isObject_Object() {}
122
+func (*Object_Config) isObject_Object()    {}
122 123
 
123 124
 func (m *Object) GetObject() isObject_Object {
124 125
 	if m != nil {
... ...
@@ -183,6 +188,13 @@ func (m *Object) GetExtension() *Extension {
183 183
 	return nil
184 184
 }
185 185
 
186
+func (m *Object) GetConfig() *Config {
187
+	if x, ok := m.GetObject().(*Object_Config); ok {
188
+		return x.Config
189
+	}
190
+	return nil
191
+}
192
+
186 193
 // XXX_OneofFuncs is for the internal use of the proto package.
187 194
 func (*Object) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
188 195
 	return _Object_OneofMarshaler, _Object_OneofUnmarshaler, _Object_OneofSizer, []interface{}{
... ...
@@ -194,6 +206,7 @@ func (*Object) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error,
194 194
 		(*Object_Secret)(nil),
195 195
 		(*Object_Resource)(nil),
196 196
 		(*Object_Extension)(nil),
197
+		(*Object_Config)(nil),
197 198
 	}
198 199
 }
199 200
 
... ...
@@ -241,6 +254,11 @@ func _Object_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
241 241
 		if err := b.EncodeMessage(x.Extension); err != nil {
242 242
 			return err
243 243
 		}
244
+	case *Object_Config:
245
+		_ = b.EncodeVarint(9<<3 | proto.WireBytes)
246
+		if err := b.EncodeMessage(x.Config); err != nil {
247
+			return err
248
+		}
244 249
 	case nil:
245 250
 	default:
246 251
 		return fmt.Errorf("Object.Object has unexpected type %T", x)
... ...
@@ -315,6 +333,14 @@ func _Object_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer)
315 315
 		err := b.DecodeMessage(msg)
316 316
 		m.Object = &Object_Extension{msg}
317 317
 		return true, err
318
+	case 9: // Object.config
319
+		if wire != proto.WireBytes {
320
+			return true, proto.ErrInternalBadWireType
321
+		}
322
+		msg := new(Config)
323
+		err := b.DecodeMessage(msg)
324
+		m.Object = &Object_Config{msg}
325
+		return true, err
318 326
 	default:
319 327
 		return false, nil
320 328
 	}
... ...
@@ -364,6 +390,11 @@ func _Object_OneofSizer(msg proto.Message) (n int) {
364 364
 		n += proto.SizeVarint(8<<3 | proto.WireBytes)
365 365
 		n += proto.SizeVarint(uint64(s))
366 366
 		n += s
367
+	case *Object_Config:
368
+		s := proto.Size(x.Config)
369
+		n += proto.SizeVarint(9<<3 | proto.WireBytes)
370
+		n += proto.SizeVarint(uint64(s))
371
+		n += s
367 372
 	case nil:
368 373
 	default:
369 374
 		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
... ...
@@ -412,6 +443,7 @@ type SelectBy struct {
412 412
 	//	*SelectBy_Membership
413 413
 	//	*SelectBy_ReferencedNetworkID
414 414
 	//	*SelectBy_ReferencedSecretID
415
+	//	*SelectBy_ReferencedConfigID
415 416
 	//	*SelectBy_Kind
416 417
 	By isSelectBy_By `protobuf_oneof:"By"`
417 418
 }
... ...
@@ -468,6 +500,9 @@ type SelectBy_ReferencedNetworkID struct {
468 468
 type SelectBy_ReferencedSecretID struct {
469 469
 	ReferencedSecretID string `protobuf:"bytes,14,opt,name=referenced_secret_id,json=referencedSecretId,proto3,oneof"`
470 470
 }
471
+type SelectBy_ReferencedConfigID struct {
472
+	ReferencedConfigID string `protobuf:"bytes,16,opt,name=referenced_config_id,json=referencedConfigId,proto3,oneof"`
473
+}
471 474
 type SelectBy_Kind struct {
472 475
 	Kind string `protobuf:"bytes,15,opt,name=kind,proto3,oneof"`
473 476
 }
... ...
@@ -486,6 +521,7 @@ func (*SelectBy_Role) isSelectBy_By()                {}
486 486
 func (*SelectBy_Membership) isSelectBy_By()          {}
487 487
 func (*SelectBy_ReferencedNetworkID) isSelectBy_By() {}
488 488
 func (*SelectBy_ReferencedSecretID) isSelectBy_By()  {}
489
+func (*SelectBy_ReferencedConfigID) isSelectBy_By()  {}
489 490
 func (*SelectBy_Kind) isSelectBy_By()                {}
490 491
 
491 492
 func (m *SelectBy) GetBy() isSelectBy_By {
... ...
@@ -593,6 +629,13 @@ func (m *SelectBy) GetReferencedSecretID() string {
593 593
 	return ""
594 594
 }
595 595
 
596
+func (m *SelectBy) GetReferencedConfigID() string {
597
+	if x, ok := m.GetBy().(*SelectBy_ReferencedConfigID); ok {
598
+		return x.ReferencedConfigID
599
+	}
600
+	return ""
601
+}
602
+
596 603
 func (m *SelectBy) GetKind() string {
597 604
 	if x, ok := m.GetBy().(*SelectBy_Kind); ok {
598 605
 		return x.Kind
... ...
@@ -617,6 +660,7 @@ func (*SelectBy) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) erro
617 617
 		(*SelectBy_Membership)(nil),
618 618
 		(*SelectBy_ReferencedNetworkID)(nil),
619 619
 		(*SelectBy_ReferencedSecretID)(nil),
620
+		(*SelectBy_ReferencedConfigID)(nil),
620 621
 		(*SelectBy_Kind)(nil),
621 622
 	}
622 623
 }
... ...
@@ -673,6 +717,9 @@ func _SelectBy_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
673 673
 	case *SelectBy_ReferencedSecretID:
674 674
 		_ = b.EncodeVarint(14<<3 | proto.WireBytes)
675 675
 		_ = b.EncodeStringBytes(x.ReferencedSecretID)
676
+	case *SelectBy_ReferencedConfigID:
677
+		_ = b.EncodeVarint(16<<3 | proto.WireBytes)
678
+		_ = b.EncodeStringBytes(x.ReferencedConfigID)
676 679
 	case *SelectBy_Kind:
677 680
 		_ = b.EncodeVarint(15<<3 | proto.WireBytes)
678 681
 		_ = b.EncodeStringBytes(x.Kind)
... ...
@@ -787,6 +834,13 @@ func _SelectBy_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffe
787 787
 		x, err := b.DecodeStringBytes()
788 788
 		m.By = &SelectBy_ReferencedSecretID{x}
789 789
 		return true, err
790
+	case 16: // By.referenced_config_id
791
+		if wire != proto.WireBytes {
792
+			return true, proto.ErrInternalBadWireType
793
+		}
794
+		x, err := b.DecodeStringBytes()
795
+		m.By = &SelectBy_ReferencedConfigID{x}
796
+		return true, err
790 797
 	case 15: // By.kind
791 798
 		if wire != proto.WireBytes {
792 799
 			return true, proto.ErrInternalBadWireType
... ...
@@ -859,6 +913,10 @@ func _SelectBy_OneofSizer(msg proto.Message) (n int) {
859 859
 		n += proto.SizeVarint(14<<3 | proto.WireBytes)
860 860
 		n += proto.SizeVarint(uint64(len(x.ReferencedSecretID)))
861 861
 		n += len(x.ReferencedSecretID)
862
+	case *SelectBy_ReferencedConfigID:
863
+		n += proto.SizeVarint(16<<3 | proto.WireBytes)
864
+		n += proto.SizeVarint(uint64(len(x.ReferencedConfigID)))
865
+		n += len(x.ReferencedConfigID)
862 866
 	case *SelectBy_Kind:
863 867
 		n += proto.SizeVarint(15<<3 | proto.WireBytes)
864 868
 		n += proto.SizeVarint(uint64(len(x.Kind)))
... ...
@@ -1034,6 +1092,12 @@ func (m *Object) CopyFrom(src interface{}) {
1034 1034
 			}
1035 1035
 			github_com_docker_swarmkit_api_deepcopy.Copy(v.Extension, o.GetExtension())
1036 1036
 			m.Object = &v
1037
+		case *Object_Config:
1038
+			v := Object_Config{
1039
+				Config: &Config{},
1040
+			}
1041
+			github_com_docker_swarmkit_api_deepcopy.Copy(v.Config, o.GetConfig())
1042
+			m.Object = &v
1037 1043
 		}
1038 1044
 	}
1039 1045
 
... ...
@@ -1157,6 +1221,11 @@ func (m *SelectBy) CopyFrom(src interface{}) {
1157 1157
 				ReferencedSecretID: o.GetReferencedSecretID(),
1158 1158
 			}
1159 1159
 			m.By = &v
1160
+		case *SelectBy_ReferencedConfigID:
1161
+			v := SelectBy_ReferencedConfigID{
1162
+				ReferencedConfigID: o.GetReferencedConfigID(),
1163
+			}
1164
+			m.By = &v
1160 1165
 		case *SelectBy_Kind:
1161 1166
 			v := SelectBy_Kind{
1162 1167
 				Kind: o.GetKind(),
... ...
@@ -1513,6 +1582,20 @@ func (m *Object_Extension) MarshalTo(dAtA []byte) (int, error) {
1513 1513
 	}
1514 1514
 	return i, nil
1515 1515
 }
1516
+func (m *Object_Config) MarshalTo(dAtA []byte) (int, error) {
1517
+	i := 0
1518
+	if m.Config != nil {
1519
+		dAtA[i] = 0x4a
1520
+		i++
1521
+		i = encodeVarintStore(dAtA, i, uint64(m.Config.Size()))
1522
+		n10, err := m.Config.MarshalTo(dAtA[i:])
1523
+		if err != nil {
1524
+			return 0, err
1525
+		}
1526
+		i += n10
1527
+	}
1528
+	return i, nil
1529
+}
1516 1530
 func (m *SelectBySlot) Marshal() (dAtA []byte, err error) {
1517 1531
 	size := m.Size()
1518 1532
 	dAtA = make([]byte, size)
... ...
@@ -1594,11 +1677,11 @@ func (m *SelectBy) MarshalTo(dAtA []byte) (int, error) {
1594 1594
 	var l int
1595 1595
 	_ = l
1596 1596
 	if m.By != nil {
1597
-		nn10, err := m.By.MarshalTo(dAtA[i:])
1597
+		nn11, err := m.By.MarshalTo(dAtA[i:])
1598 1598
 		if err != nil {
1599 1599
 			return 0, err
1600 1600
 		}
1601
-		i += nn10
1601
+		i += nn11
1602 1602
 	}
1603 1603
 	return i, nil
1604 1604
 }
... ...
@@ -1641,11 +1724,11 @@ func (m *SelectBy_Custom) MarshalTo(dAtA []byte) (int, error) {
1641 1641
 		dAtA[i] = 0x2a
1642 1642
 		i++
1643 1643
 		i = encodeVarintStore(dAtA, i, uint64(m.Custom.Size()))
1644
-		n11, err := m.Custom.MarshalTo(dAtA[i:])
1644
+		n12, err := m.Custom.MarshalTo(dAtA[i:])
1645 1645
 		if err != nil {
1646 1646
 			return 0, err
1647 1647
 		}
1648
-		i += n11
1648
+		i += n12
1649 1649
 	}
1650 1650
 	return i, nil
1651 1651
 }
... ...
@@ -1655,11 +1738,11 @@ func (m *SelectBy_CustomPrefix) MarshalTo(dAtA []byte) (int, error) {
1655 1655
 		dAtA[i] = 0x32
1656 1656
 		i++
1657 1657
 		i = encodeVarintStore(dAtA, i, uint64(m.CustomPrefix.Size()))
1658
-		n12, err := m.CustomPrefix.MarshalTo(dAtA[i:])
1658
+		n13, err := m.CustomPrefix.MarshalTo(dAtA[i:])
1659 1659
 		if err != nil {
1660 1660
 			return 0, err
1661 1661
 		}
1662
-		i += n12
1662
+		i += n13
1663 1663
 	}
1664 1664
 	return i, nil
1665 1665
 }
... ...
@@ -1685,11 +1768,11 @@ func (m *SelectBy_Slot) MarshalTo(dAtA []byte) (int, error) {
1685 1685
 		dAtA[i] = 0x4a
1686 1686
 		i++
1687 1687
 		i = encodeVarintStore(dAtA, i, uint64(m.Slot.Size()))
1688
-		n13, err := m.Slot.MarshalTo(dAtA[i:])
1688
+		n14, err := m.Slot.MarshalTo(dAtA[i:])
1689 1689
 		if err != nil {
1690 1690
 			return 0, err
1691 1691
 		}
1692
-		i += n13
1692
+		i += n14
1693 1693
 	}
1694 1694
 	return i, nil
1695 1695
 }
... ...
@@ -1738,6 +1821,16 @@ func (m *SelectBy_Kind) MarshalTo(dAtA []byte) (int, error) {
1738 1738
 	i += copy(dAtA[i:], m.Kind)
1739 1739
 	return i, nil
1740 1740
 }
1741
+func (m *SelectBy_ReferencedConfigID) MarshalTo(dAtA []byte) (int, error) {
1742
+	i := 0
1743
+	dAtA[i] = 0x82
1744
+	i++
1745
+	dAtA[i] = 0x1
1746
+	i++
1747
+	i = encodeVarintStore(dAtA, i, uint64(len(m.ReferencedConfigID)))
1748
+	i += copy(dAtA[i:], m.ReferencedConfigID)
1749
+	return i, nil
1750
+}
1741 1751
 func (m *WatchRequest) Marshal() (dAtA []byte, err error) {
1742 1752
 	size := m.Size()
1743 1753
 	dAtA = make([]byte, size)
... ...
@@ -1769,11 +1862,11 @@ func (m *WatchRequest) MarshalTo(dAtA []byte) (int, error) {
1769 1769
 		dAtA[i] = 0x12
1770 1770
 		i++
1771 1771
 		i = encodeVarintStore(dAtA, i, uint64(m.ResumeFrom.Size()))
1772
-		n14, err := m.ResumeFrom.MarshalTo(dAtA[i:])
1772
+		n15, err := m.ResumeFrom.MarshalTo(dAtA[i:])
1773 1773
 		if err != nil {
1774 1774
 			return 0, err
1775 1775
 		}
1776
-		i += n14
1776
+		i += n15
1777 1777
 	}
1778 1778
 	if m.IncludeOldObject {
1779 1779
 		dAtA[i] = 0x18
... ...
@@ -1860,11 +1953,11 @@ func (m *WatchMessage) MarshalTo(dAtA []byte) (int, error) {
1860 1860
 		dAtA[i] = 0x12
1861 1861
 		i++
1862 1862
 		i = encodeVarintStore(dAtA, i, uint64(m.Version.Size()))
1863
-		n15, err := m.Version.MarshalTo(dAtA[i:])
1863
+		n16, err := m.Version.MarshalTo(dAtA[i:])
1864 1864
 		if err != nil {
1865 1865
 			return 0, err
1866 1866
 		}
1867
-		i += n15
1867
+		i += n16
1868 1868
 	}
1869 1869
 	return i, nil
1870 1870
 }
... ...
@@ -1893,21 +1986,21 @@ func (m *WatchMessage_Event) MarshalTo(dAtA []byte) (int, error) {
1893 1893
 		dAtA[i] = 0x12
1894 1894
 		i++
1895 1895
 		i = encodeVarintStore(dAtA, i, uint64(m.Object.Size()))
1896
-		n16, err := m.Object.MarshalTo(dAtA[i:])
1896
+		n17, err := m.Object.MarshalTo(dAtA[i:])
1897 1897
 		if err != nil {
1898 1898
 			return 0, err
1899 1899
 		}
1900
-		i += n16
1900
+		i += n17
1901 1901
 	}
1902 1902
 	if m.OldObject != nil {
1903 1903
 		dAtA[i] = 0x1a
1904 1904
 		i++
1905 1905
 		i = encodeVarintStore(dAtA, i, uint64(m.OldObject.Size()))
1906
-		n17, err := m.OldObject.MarshalTo(dAtA[i:])
1906
+		n18, err := m.OldObject.MarshalTo(dAtA[i:])
1907 1907
 		if err != nil {
1908 1908
 			return 0, err
1909 1909
 		}
1910
-		i += n17
1910
+		i += n18
1911 1911
 	}
1912 1912
 	return i, nil
1913 1913
 }
... ...
@@ -2144,6 +2237,15 @@ func (m *Object_Extension) Size() (n int) {
2144 2144
 	}
2145 2145
 	return n
2146 2146
 }
2147
+func (m *Object_Config) Size() (n int) {
2148
+	var l int
2149
+	_ = l
2150
+	if m.Config != nil {
2151
+		l = m.Config.Size()
2152
+		n += 1 + l + sovStore(uint64(l))
2153
+	}
2154
+	return n
2155
+}
2147 2156
 func (m *SelectBySlot) Size() (n int) {
2148 2157
 	var l int
2149 2158
 	_ = l
... ...
@@ -2292,6 +2394,13 @@ func (m *SelectBy_Kind) Size() (n int) {
2292 2292
 	n += 1 + l + sovStore(uint64(l))
2293 2293
 	return n
2294 2294
 }
2295
+func (m *SelectBy_ReferencedConfigID) Size() (n int) {
2296
+	var l int
2297
+	_ = l
2298
+	l = len(m.ReferencedConfigID)
2299
+	n += 2 + l + sovStore(uint64(l))
2300
+	return n
2301
+}
2295 2302
 func (m *WatchRequest) Size() (n int) {
2296 2303
 	var l int
2297 2304
 	_ = l
... ...
@@ -2466,6 +2575,16 @@ func (this *Object_Extension) String() string {
2466 2466
 	}, "")
2467 2467
 	return s
2468 2468
 }
2469
+func (this *Object_Config) String() string {
2470
+	if this == nil {
2471
+		return "nil"
2472
+	}
2473
+	s := strings.Join([]string{`&Object_Config{`,
2474
+		`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
2475
+		`}`,
2476
+	}, "")
2477
+	return s
2478
+}
2469 2479
 func (this *SelectBySlot) String() string {
2470 2480
 	if this == nil {
2471 2481
 		return "nil"
... ...
@@ -2649,6 +2768,16 @@ func (this *SelectBy_Kind) String() string {
2649 2649
 	}, "")
2650 2650
 	return s
2651 2651
 }
2652
+func (this *SelectBy_ReferencedConfigID) String() string {
2653
+	if this == nil {
2654
+		return "nil"
2655
+	}
2656
+	s := strings.Join([]string{`&SelectBy_ReferencedConfigID{`,
2657
+		`ReferencedConfigID:` + fmt.Sprintf("%v", this.ReferencedConfigID) + `,`,
2658
+		`}`,
2659
+	}, "")
2660
+	return s
2661
+}
2652 2662
 func (this *WatchRequest) String() string {
2653 2663
 	if this == nil {
2654 2664
 		return "nil"
... ...
@@ -2989,6 +3118,38 @@ func (m *Object) Unmarshal(dAtA []byte) error {
2989 2989
 			}
2990 2990
 			m.Object = &Object_Extension{v}
2991 2991
 			iNdEx = postIndex
2992
+		case 9:
2993
+			if wireType != 2 {
2994
+				return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
2995
+			}
2996
+			var msglen int
2997
+			for shift := uint(0); ; shift += 7 {
2998
+				if shift >= 64 {
2999
+					return ErrIntOverflowStore
3000
+				}
3001
+				if iNdEx >= l {
3002
+					return io.ErrUnexpectedEOF
3003
+				}
3004
+				b := dAtA[iNdEx]
3005
+				iNdEx++
3006
+				msglen |= (int(b) & 0x7F) << shift
3007
+				if b < 0x80 {
3008
+					break
3009
+				}
3010
+			}
3011
+			if msglen < 0 {
3012
+				return ErrInvalidLengthStore
3013
+			}
3014
+			postIndex := iNdEx + msglen
3015
+			if postIndex > l {
3016
+				return io.ErrUnexpectedEOF
3017
+			}
3018
+			v := &Config{}
3019
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
3020
+				return err
3021
+			}
3022
+			m.Object = &Object_Config{v}
3023
+			iNdEx = postIndex
2992 3024
 		default:
2993 3025
 			iNdEx = preIndex
2994 3026
 			skippy, err := skipStore(dAtA[iNdEx:])
... ...
@@ -3691,6 +3852,35 @@ func (m *SelectBy) Unmarshal(dAtA []byte) error {
3691 3691
 			}
3692 3692
 			m.By = &SelectBy_Kind{string(dAtA[iNdEx:postIndex])}
3693 3693
 			iNdEx = postIndex
3694
+		case 16:
3695
+			if wireType != 2 {
3696
+				return fmt.Errorf("proto: wrong wireType = %d for field ReferencedConfigID", wireType)
3697
+			}
3698
+			var stringLen uint64
3699
+			for shift := uint(0); ; shift += 7 {
3700
+				if shift >= 64 {
3701
+					return ErrIntOverflowStore
3702
+				}
3703
+				if iNdEx >= l {
3704
+					return io.ErrUnexpectedEOF
3705
+				}
3706
+				b := dAtA[iNdEx]
3707
+				iNdEx++
3708
+				stringLen |= (uint64(b) & 0x7F) << shift
3709
+				if b < 0x80 {
3710
+					break
3711
+				}
3712
+			}
3713
+			intStringLen := int(stringLen)
3714
+			if intStringLen < 0 {
3715
+				return ErrInvalidLengthStore
3716
+			}
3717
+			postIndex := iNdEx + intStringLen
3718
+			if postIndex > l {
3719
+				return io.ErrUnexpectedEOF
3720
+			}
3721
+			m.By = &SelectBy_ReferencedConfigID{string(dAtA[iNdEx:postIndex])}
3722
+			iNdEx = postIndex
3694 3723
 		default:
3695 3724
 			iNdEx = preIndex
3696 3725
 			skippy, err := skipStore(dAtA[iNdEx:])
... ...
@@ -4332,76 +4522,78 @@ var (
4332 4332
 func init() { proto.RegisterFile("store.proto", fileDescriptorStore) }
4333 4333
 
4334 4334
 var fileDescriptorStore = []byte{
4335
-	// 1127 bytes of a gzipped FileDescriptorProto
4336
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x96, 0x4f, 0x6f, 0x1b, 0xc5,
4337
-	0x1b, 0xc7, 0xbd, 0x8e, 0xb3, 0xb6, 0x1f, 0xc7, 0x6d, 0x34, 0x49, 0xdb, 0xfd, 0xf9, 0x57, 0x6c,
4338
-	0x63, 0x04, 0x54, 0xb4, 0xb8, 0x10, 0x4a, 0x11, 0x50, 0x90, 0x62, 0xc7, 0xc8, 0xa6, 0x8a, 0x13,
4339
-	0x8d, 0x93, 0xe6, 0x68, 0x6d, 0x76, 0x9f, 0xa4, 0x8b, 0xf7, 0x8f, 0x99, 0x1d, 0x3b, 0xcd, 0x8d,
4340
-	0x23, 0xea, 0x1d, 0x89, 0x4b, 0xb9, 0xc0, 0x99, 0x0b, 0x37, 0x78, 0x03, 0x15, 0x07, 0xc4, 0x11,
4341
-	0x2e, 0x16, 0xf5, 0x0b, 0xe0, 0x15, 0x70, 0x40, 0x33, 0x3b, 0x9b, 0x3f, 0xee, 0x3a, 0xa5, 0x27,
4342
-	0xcf, 0xcc, 0x7e, 0x3f, 0xcf, 0x3e, 0xf3, 0x7c, 0x67, 0x1e, 0x2f, 0x14, 0x42, 0x1e, 0x30, 0xac,
4343
-	0x0f, 0x59, 0xc0, 0x03, 0x42, 0xec, 0xc0, 0x1a, 0x20, 0xab, 0x87, 0x47, 0x26, 0xf3, 0x06, 0x0e,
4344
-	0xaf, 0x8f, 0xdf, 0x2d, 0x15, 0xc2, 0x21, 0x5a, 0x61, 0x24, 0x28, 0x15, 0x83, 0xfd, 0x2f, 0xd0,
4345
-	0xe2, 0xf1, 0xb4, 0xc0, 0x8f, 0x87, 0x18, 0x4f, 0x56, 0x0f, 0x83, 0xc3, 0x40, 0x0e, 0x6f, 0x8b,
4346
-	0x91, 0x5a, 0x5d, 0x19, 0xba, 0xa3, 0x43, 0xc7, 0xbf, 0x1d, 0xfd, 0x44, 0x8b, 0xb5, 0xdf, 0x16,
4347
-	0x40, 0xdf, 0x92, 0x91, 0x48, 0x1d, 0x32, 0x7e, 0x60, 0xa3, 0xa1, 0x55, 0xb5, 0x1b, 0x85, 0x35,
4348
-	0xa3, 0xfe, 0x7c, 0x06, 0xf5, 0x6e, 0x60, 0x63, 0x3b, 0x45, 0xa5, 0x8e, 0x7c, 0x00, 0xd9, 0x10,
4349
-	0xd9, 0xd8, 0xb1, 0xd0, 0x48, 0x4b, 0xe4, 0xff, 0x49, 0x48, 0x2f, 0x92, 0xb4, 0x53, 0x34, 0x56,
4350
-	0x0b, 0xd0, 0x47, 0x7e, 0x14, 0xb0, 0x81, 0xb1, 0x30, 0x1f, 0xec, 0x46, 0x12, 0x01, 0x2a, 0xb5,
4351
-	0xc8, 0x90, 0x9b, 0xe1, 0xc0, 0xc8, 0xcc, 0xcf, 0x70, 0xc7, 0x0c, 0x05, 0x22, 0x75, 0xe2, 0x45,
4352
-	0x96, 0x3b, 0x0a, 0x39, 0x32, 0x63, 0x71, 0xfe, 0x8b, 0x9a, 0x91, 0x44, 0xbc, 0x48, 0xa9, 0xc9,
4353
-	0x1d, 0xd0, 0x43, 0xb4, 0x18, 0x72, 0x43, 0x97, 0x5c, 0x29, 0x79, 0x67, 0x42, 0xd1, 0x4e, 0x51,
4354
-	0xa5, 0x25, 0x1f, 0x41, 0x8e, 0x61, 0x18, 0x8c, 0x98, 0x85, 0x46, 0x56, 0x72, 0xd7, 0x93, 0x38,
4355
-	0xaa, 0x34, 0xed, 0x14, 0x3d, 0xd1, 0x93, 0x4f, 0x20, 0x8f, 0x8f, 0x38, 0xfa, 0xa1, 0x13, 0xf8,
4356
-	0x46, 0x4e, 0xc2, 0xaf, 0x24, 0xc1, 0xad, 0x58, 0xd4, 0x4e, 0xd1, 0x53, 0xa2, 0x91, 0x8b, 0x5d,
4357
-	0xac, 0x6d, 0xc3, 0x52, 0x0f, 0x5d, 0xb4, 0x78, 0xe3, 0xb8, 0xe7, 0x06, 0x9c, 0xdc, 0x02, 0x50,
4358
-	0x75, 0xef, 0x3b, 0xb6, 0xf4, 0x36, 0xdf, 0x28, 0x4e, 0x27, 0x95, 0xbc, 0x32, 0xa6, 0xb3, 0x41,
4359
-	0xf3, 0x4a, 0xd0, 0xb1, 0x09, 0x81, 0x4c, 0xe8, 0x06, 0x5c, 0x1a, 0x9a, 0xa1, 0x72, 0x5c, 0xdb,
4360
-	0x86, 0x4b, 0x71, 0xc4, 0xe6, 0x28, 0xe4, 0x81, 0x27, 0x54, 0x03, 0xc7, 0x57, 0xd1, 0xa8, 0x1c,
4361
-	0x93, 0x55, 0x58, 0x74, 0x7c, 0x1b, 0x1f, 0x49, 0x34, 0x4f, 0xa3, 0x89, 0x58, 0x1d, 0x9b, 0xee,
4362
-	0x08, 0xa5, 0xd1, 0x79, 0x1a, 0x4d, 0x6a, 0xdf, 0xe9, 0x90, 0x8b, 0x43, 0x12, 0x03, 0xd2, 0x27,
4363
-	0x89, 0xe9, 0xd3, 0x49, 0x25, 0xdd, 0xd9, 0x68, 0xa7, 0x68, 0xda, 0xb1, 0xc9, 0x4d, 0xc8, 0x3b,
4364
-	0x76, 0x7f, 0xc8, 0xf0, 0xc0, 0x51, 0x61, 0x1b, 0x4b, 0xd3, 0x49, 0x25, 0xd7, 0xd9, 0xd8, 0x96,
4365
-	0x6b, 0xa2, 0x80, 0x8e, 0x1d, 0x8d, 0xc9, 0x2a, 0x64, 0x7c, 0xd3, 0x53, 0x2f, 0x92, 0x67, 0xd4,
4366
-	0xf4, 0x90, 0xbc, 0x0a, 0x05, 0xf1, 0x1b, 0x07, 0xc9, 0xa8, 0x87, 0x20, 0x16, 0x15, 0x78, 0x0f,
4367
-	0x74, 0x4b, 0x6e, 0x4b, 0x9d, 0x91, 0x5a, 0xb2, 0xd7, 0x67, 0x0b, 0x20, 0x3c, 0x8f, 0x18, 0xd2,
4368
-	0x81, 0x62, 0x34, 0x8a, 0x5f, 0xa1, 0xbf, 0x44, 0x90, 0xa5, 0x08, 0x55, 0x89, 0xd4, 0xcf, 0x39,
4369
-	0x95, 0x4d, 0x70, 0x4a, 0x78, 0x7e, 0xea, 0xd5, 0xeb, 0x90, 0x15, 0xf7, 0x50, 0x88, 0x73, 0x52,
4370
-	0x0c, 0xd3, 0x49, 0x45, 0x17, 0x57, 0x54, 0x2a, 0x75, 0xf1, 0xb0, 0x63, 0x93, 0xbb, 0xca, 0xd2,
4371
-	0xbc, 0x4c, 0xac, 0x7a, 0x51, 0x62, 0xe2, 0xc0, 0x88, 0xd2, 0x09, 0x3d, 0xd9, 0x80, 0xa2, 0x8d,
4372
-	0xa1, 0xc3, 0xd0, 0xee, 0x87, 0xdc, 0xe4, 0x68, 0x40, 0x55, 0xbb, 0x71, 0x29, 0xf9, 0x54, 0x8a,
4373
-	0x5b, 0xd7, 0x13, 0x22, 0xb1, 0x29, 0x45, 0xc9, 0x39, 0x59, 0x83, 0x0c, 0x0b, 0x5c, 0x34, 0x0a,
4374
-	0x12, 0xbe, 0x3e, 0xaf, 0xa9, 0xd0, 0xc0, 0x95, 0x8d, 0x45, 0x68, 0x49, 0x07, 0xc0, 0x43, 0x6f,
4375
-	0x1f, 0x59, 0xf8, 0xd0, 0x19, 0x1a, 0x4b, 0x92, 0x7c, 0x73, 0x1e, 0xd9, 0x1b, 0xa2, 0x55, 0xdf,
4376
-	0x3c, 0x91, 0x0b, 0x73, 0x4f, 0x61, 0xb2, 0x09, 0x57, 0x18, 0x1e, 0x20, 0x43, 0xdf, 0x42, 0xbb,
4377
-	0xaf, 0xfa, 0x88, 0xa8, 0x58, 0x51, 0x56, 0xec, 0xda, 0x74, 0x52, 0x59, 0xa1, 0x27, 0x02, 0xd5,
4378
-	0x72, 0x64, 0xf9, 0x56, 0xd8, 0x73, 0xcb, 0x36, 0xf9, 0x1c, 0x56, 0xcf, 0x84, 0x8b, 0xae, 0xbd,
4379
-	0x88, 0x76, 0x49, 0x46, 0xbb, 0x3a, 0x9d, 0x54, 0xc8, 0x69, 0xb4, 0xa8, 0x3f, 0xc8, 0x60, 0x84,
4380
-	0xcd, 0xae, 0x8a, 0x0b, 0x13, 0x5d, 0xa2, 0xcb, 0xf1, 0x81, 0x15, 0xb3, 0x46, 0x06, 0xd2, 0x8d,
4381
-	0xe3, 0xda, 0x9f, 0x69, 0x58, 0xda, 0x33, 0xb9, 0xf5, 0x90, 0xe2, 0x97, 0x23, 0x0c, 0x39, 0x69,
4382
-	0x41, 0x16, 0x7d, 0xce, 0x1c, 0x0c, 0x0d, 0xad, 0xba, 0x70, 0xa3, 0xb0, 0x76, 0x33, 0xa9, 0x1e,
4383
-	0x67, 0x91, 0x68, 0xd2, 0xf2, 0x39, 0x3b, 0xa6, 0x31, 0x4b, 0xee, 0x41, 0x81, 0x61, 0x38, 0xf2,
4384
-	0xb0, 0x7f, 0xc0, 0x02, 0xef, 0xa2, 0xb6, 0xfd, 0x00, 0x99, 0x68, 0x2c, 0x14, 0x22, 0xfd, 0x67,
4385
-	0x2c, 0xf0, 0xc8, 0x2d, 0x20, 0x8e, 0x6f, 0xb9, 0x23, 0x1b, 0xfb, 0x81, 0x6b, 0xf7, 0xa3, 0x3f,
4386
-	0x20, 0x79, 0xe1, 0x72, 0x74, 0x59, 0x3d, 0xd9, 0x72, 0xed, 0xa8, 0x11, 0x95, 0xbe, 0xd1, 0x00,
4387
-	0x4e, 0x73, 0x48, 0xec, 0x19, 0x1f, 0x83, 0x6e, 0x5a, 0x5c, 0x74, 0xbc, 0xb4, 0x34, 0xf9, 0xb5,
4388
-	0xb9, 0x9b, 0x5a, 0x97, 0xb2, 0xfb, 0x8e, 0x6f, 0x53, 0x85, 0x90, 0xbb, 0x90, 0x3d, 0x70, 0x5c,
4389
-	0x8e, 0x2c, 0x34, 0x16, 0x64, 0x49, 0xae, 0x5f, 0x74, 0xb4, 0x69, 0x2c, 0xae, 0xfd, 0x12, 0xd7,
4390
-	0x76, 0x13, 0xc3, 0xd0, 0x3c, 0x44, 0xf2, 0x29, 0xe8, 0x38, 0x46, 0x9f, 0xc7, 0xa5, 0x7d, 0x63,
4391
-	0x6e, 0x16, 0x8a, 0xa8, 0xb7, 0x84, 0x9c, 0x2a, 0x8a, 0xbc, 0x0f, 0xd9, 0x71, 0x54, 0xad, 0xff,
4392
-	0x52, 0xd0, 0x58, 0x5b, 0xfa, 0x49, 0x83, 0x45, 0x19, 0xe8, 0x4c, 0x19, 0xb4, 0x97, 0x2f, 0xc3,
4393
-	0x1a, 0xe8, 0xca, 0x88, 0xf4, 0xfc, 0xbf, 0xaa, 0xc8, 0x12, 0xaa, 0x94, 0xe4, 0x43, 0x80, 0x19,
4394
-	0x03, 0x2f, 0xe6, 0xf2, 0x41, 0xec, 0xea, 0x5b, 0xff, 0x68, 0x70, 0x79, 0x26, 0x15, 0x72, 0x07,
4395
-	0x56, 0xf7, 0xd6, 0x77, 0x9a, 0xed, 0xfe, 0x7a, 0x73, 0xa7, 0xb3, 0xd5, 0xed, 0xef, 0x76, 0xef,
4396
-	0x77, 0xb7, 0xf6, 0xba, 0xcb, 0xa9, 0x52, 0xe9, 0xf1, 0x93, 0xea, 0xd5, 0x19, 0xf9, 0xae, 0x3f,
4397
-	0xf0, 0x83, 0x23, 0x91, 0xf8, 0xca, 0x39, 0xaa, 0x49, 0x5b, 0xeb, 0x3b, 0xad, 0x65, 0xad, 0xf4,
4398
-	0xbf, 0xc7, 0x4f, 0xaa, 0x57, 0x66, 0xa0, 0x26, 0xc3, 0xa8, 0x9b, 0x9c, 0x67, 0x76, 0xb7, 0x37,
4399
-	0x04, 0x93, 0x4e, 0x64, 0x76, 0x87, 0x76, 0x12, 0x43, 0x5b, 0x9b, 0x5b, 0x0f, 0x5a, 0xcb, 0x99,
4400
-	0x44, 0x86, 0xa2, 0x17, 0x8c, 0xb1, 0x74, 0xed, 0xeb, 0xef, 0xcb, 0xa9, 0x9f, 0x7f, 0x28, 0xcf,
4401
-	0x6e, 0x75, 0xcd, 0x83, 0xc5, 0x9e, 0xf8, 0x4a, 0x23, 0x36, 0x2c, 0xca, 0x67, 0xa4, 0xfa, 0xa2,
4402
-	0x8b, 0x58, 0xaa, 0xbe, 0xe8, 0x3c, 0xd5, 0xae, 0xfc, 0xfa, 0xe3, 0xdf, 0xdf, 0xa6, 0x2f, 0x43,
4403
-	0x51, 0x2a, 0xde, 0xf6, 0x4c, 0xdf, 0x3c, 0x44, 0xf6, 0x8e, 0xd6, 0x30, 0x9e, 0x3e, 0x2b, 0xa7,
4404
-	0xfe, 0x78, 0x56, 0x4e, 0x7d, 0x35, 0x2d, 0x6b, 0x4f, 0xa7, 0x65, 0xed, 0xf7, 0x69, 0x59, 0xfb,
4405
-	0x6b, 0x5a, 0xd6, 0xf6, 0x75, 0xf9, 0xf9, 0xf6, 0xde, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa9,
4406
-	0xa5, 0x8e, 0xe6, 0x35, 0x0a, 0x00, 0x00,
4335
+	// 1160 bytes of a gzipped FileDescriptorProto
4336
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x96, 0xbd, 0x73, 0x1b, 0xc5,
4337
+	0x1b, 0xc7, 0x75, 0x8a, 0x7c, 0x92, 0x1e, 0xd9, 0x89, 0x67, 0xed, 0x24, 0xf7, 0xd3, 0x2f, 0xc8,
4338
+	0x42, 0x0c, 0x90, 0x21, 0x41, 0x01, 0x13, 0xc2, 0x00, 0x81, 0x19, 0x4b, 0x16, 0x23, 0x91, 0xf1,
4339
+	0xcb, 0xac, 0xec, 0xa4, 0xd4, 0x5c, 0xee, 0x1e, 0x2b, 0x87, 0xee, 0x6e, 0xc5, 0xde, 0x49, 0x89,
4340
+	0x3b, 0x0a, 0x0a, 0x26, 0x3d, 0x33, 0x34, 0xa9, 0xa0, 0xa6, 0xa1, 0x83, 0x7f, 0x20, 0x43, 0x45,
4341
+	0x09, 0x8d, 0x86, 0xa8, 0xa4, 0xe0, 0x2f, 0xa0, 0x60, 0xf6, 0xe5, 0xfc, 0xa2, 0x9c, 0x1c, 0x52,
4342
+	0x69, 0x77, 0xef, 0xf3, 0x7d, 0xf6, 0xb9, 0xe7, 0xed, 0x04, 0xa5, 0x28, 0x66, 0x1c, 0xeb, 0x43,
4343
+	0xce, 0x62, 0x46, 0x88, 0xcb, 0x9c, 0x01, 0xf2, 0x7a, 0xf4, 0xd0, 0xe6, 0xc1, 0xc0, 0x8b, 0xeb,
4344
+	0xe3, 0x77, 0xcb, 0xa5, 0x68, 0x88, 0x4e, 0xa4, 0x80, 0xf2, 0x12, 0xbb, 0xff, 0x05, 0x3a, 0x71,
4345
+	0xb2, 0x2d, 0xc5, 0x87, 0x43, 0x4c, 0x36, 0xab, 0x7d, 0xd6, 0x67, 0x72, 0x79, 0x43, 0xac, 0xf4,
4346
+	0xe9, 0xca, 0xd0, 0x1f, 0xf5, 0xbd, 0xf0, 0x86, 0xfa, 0x51, 0x87, 0xb5, 0xaf, 0x73, 0x60, 0xee,
4347
+	0x48, 0x4b, 0xa4, 0x0e, 0xb9, 0x90, 0xb9, 0x68, 0x19, 0x55, 0xe3, 0x6a, 0x69, 0xdd, 0xaa, 0x3f,
4348
+	0xef, 0x41, 0x7d, 0x9b, 0xb9, 0xd8, 0xce, 0x50, 0xc9, 0x91, 0x0f, 0x20, 0x1f, 0x21, 0x1f, 0x7b,
4349
+	0x0e, 0x5a, 0x59, 0x29, 0xf9, 0x7f, 0x9a, 0xa4, 0xab, 0x90, 0x76, 0x86, 0x26, 0xb4, 0x10, 0x86,
4350
+	0x18, 0x3f, 0x64, 0x7c, 0x60, 0x9d, 0x9b, 0x2f, 0xdc, 0x56, 0x88, 0x10, 0x6a, 0x5a, 0x78, 0x18,
4351
+	0xdb, 0xd1, 0xc0, 0xca, 0xcd, 0xf7, 0x70, 0xcf, 0x8e, 0x84, 0x44, 0x72, 0xe2, 0x22, 0xc7, 0x1f,
4352
+	0x45, 0x31, 0x72, 0x6b, 0x61, 0xfe, 0x45, 0x4d, 0x85, 0x88, 0x8b, 0x34, 0x4d, 0x6e, 0x82, 0x19,
4353
+	0xa1, 0xc3, 0x31, 0xb6, 0x4c, 0xa9, 0x2b, 0xa7, 0xbf, 0x99, 0x20, 0xda, 0x19, 0xaa, 0x59, 0xf2,
4354
+	0x11, 0x14, 0x38, 0x46, 0x6c, 0xc4, 0x1d, 0xb4, 0xf2, 0x52, 0x77, 0x25, 0x4d, 0x47, 0x35, 0xd3,
4355
+	0xce, 0xd0, 0x23, 0x9e, 0x7c, 0x02, 0x45, 0x7c, 0x14, 0x63, 0x18, 0x79, 0x2c, 0xb4, 0x0a, 0x52,
4356
+	0xfc, 0x4a, 0x9a, 0xb8, 0x95, 0x40, 0xed, 0x0c, 0x3d, 0x56, 0x08, 0x87, 0x1d, 0x16, 0x1e, 0x78,
4357
+	0x7d, 0xab, 0x38, 0xdf, 0xe1, 0xa6, 0x24, 0x84, 0xc3, 0x8a, 0x6d, 0x14, 0x92, 0xdc, 0xd7, 0x76,
4358
+	0x61, 0xb1, 0x8b, 0x3e, 0x3a, 0x71, 0xe3, 0xb0, 0xeb, 0xb3, 0x98, 0x5c, 0x07, 0xd0, 0xd9, 0xea,
4359
+	0x79, 0xae, 0xac, 0x88, 0x62, 0x63, 0x69, 0x3a, 0x59, 0x2b, 0xea, 0x74, 0x76, 0x36, 0x69, 0x51,
4360
+	0x03, 0x1d, 0x97, 0x10, 0xc8, 0x45, 0x3e, 0x8b, 0x65, 0x19, 0xe4, 0xa8, 0x5c, 0xd7, 0x76, 0xe1,
4361
+	0x7c, 0x62, 0xb1, 0x39, 0x8a, 0x62, 0x16, 0x08, 0x6a, 0xe0, 0x85, 0xda, 0x1a, 0x95, 0x6b, 0xb2,
4362
+	0x0a, 0x0b, 0x5e, 0xe8, 0xe2, 0x23, 0x29, 0x2d, 0x52, 0xb5, 0x11, 0xa7, 0x63, 0xdb, 0x1f, 0xa1,
4363
+	0x2c, 0x8f, 0x22, 0x55, 0x9b, 0xda, 0x5f, 0x26, 0x14, 0x12, 0x93, 0xc4, 0x82, 0xec, 0x91, 0x63,
4364
+	0xe6, 0x74, 0xb2, 0x96, 0xed, 0x6c, 0xb6, 0x33, 0x34, 0xeb, 0xb9, 0xe4, 0x1a, 0x14, 0x3d, 0xb7,
4365
+	0x37, 0xe4, 0x78, 0xe0, 0x69, 0xb3, 0x8d, 0xc5, 0xe9, 0x64, 0xad, 0xd0, 0xd9, 0xdc, 0x95, 0x67,
4366
+	0x22, 0xec, 0x9e, 0xab, 0xd6, 0x64, 0x15, 0x72, 0xa1, 0x1d, 0xe8, 0x8b, 0x64, 0x65, 0xdb, 0x01,
4367
+	0x92, 0x57, 0xa1, 0x24, 0x7e, 0x13, 0x23, 0x39, 0xfd, 0x10, 0xc4, 0xa1, 0x16, 0xde, 0x06, 0xd3,
4368
+	0x91, 0xaf, 0xa5, 0x2b, 0xab, 0x96, 0x5e, 0x21, 0x27, 0x03, 0x20, 0x03, 0xaf, 0x42, 0xd1, 0x81,
4369
+	0x25, 0xb5, 0x4a, 0xae, 0x30, 0x5f, 0xc2, 0xc8, 0xa2, 0x92, 0x6a, 0x47, 0xea, 0xa7, 0x32, 0x95,
4370
+	0x4f, 0xc9, 0x94, 0xa8, 0x94, 0xe3, 0x5c, 0xbd, 0x0e, 0x79, 0xd1, 0xbd, 0x02, 0x2e, 0x48, 0x18,
4371
+	0xa6, 0x93, 0x35, 0x53, 0x34, 0xb6, 0x24, 0x4d, 0xf1, 0xb0, 0xe3, 0x92, 0x5b, 0x3a, 0xa5, 0xaa,
4372
+	0x9c, 0xaa, 0x67, 0x39, 0x26, 0x0a, 0x46, 0x84, 0x4e, 0xf0, 0x64, 0x13, 0x96, 0x5c, 0x8c, 0x3c,
4373
+	0x8e, 0x6e, 0x2f, 0x8a, 0xed, 0x18, 0x2d, 0xa8, 0x1a, 0x57, 0xcf, 0xa7, 0xd7, 0xb2, 0xe8, 0xd5,
4374
+	0xae, 0x80, 0xc4, 0x4b, 0x69, 0x95, 0xdc, 0x93, 0x75, 0xc8, 0x71, 0xe6, 0xa3, 0x55, 0x92, 0xe2,
4375
+	0x2b, 0xf3, 0x46, 0x11, 0x65, 0xbe, 0x1c, 0x47, 0x82, 0x25, 0x1d, 0x80, 0x00, 0x83, 0xfb, 0xc8,
4376
+	0xa3, 0x07, 0xde, 0xd0, 0x5a, 0x94, 0xca, 0x37, 0xe7, 0x29, 0xbb, 0x43, 0x74, 0xea, 0x5b, 0x47,
4377
+	0xb8, 0x48, 0xee, 0xb1, 0x98, 0x6c, 0xc1, 0x45, 0x8e, 0x07, 0xc8, 0x31, 0x74, 0xd0, 0xed, 0xe9,
4378
+	0xe9, 0x23, 0x22, 0xb6, 0x24, 0x23, 0x76, 0x79, 0x3a, 0x59, 0x5b, 0xa1, 0x47, 0x80, 0x1e, 0x54,
4379
+	0x32, 0x7c, 0x2b, 0xfc, 0xb9, 0x63, 0x97, 0x7c, 0x0e, 0xab, 0x27, 0xcc, 0xa9, 0x61, 0x21, 0xac,
4380
+	0x9d, 0x97, 0xd6, 0x2e, 0x4d, 0x27, 0x6b, 0xe4, 0xd8, 0x9a, 0x9a, 0x2a, 0xd2, 0x18, 0xe1, 0xb3,
4381
+	0xa7, 0xa2, 0x61, 0x54, 0x13, 0x5d, 0x48, 0x0a, 0x56, 0xb6, 0xd1, 0xe9, 0x1b, 0x54, 0x77, 0x8b,
4382
+	0x1b, 0x96, 0xd3, 0x6e, 0x50, 0x63, 0x60, 0xf6, 0x06, 0x7d, 0xea, 0x36, 0x72, 0x90, 0x6d, 0x1c,
4383
+	0xd6, 0xfe, 0xc8, 0xc2, 0xe2, 0x3d, 0x3b, 0x76, 0x1e, 0x50, 0xfc, 0x72, 0x84, 0x51, 0x4c, 0x5a,
4384
+	0x90, 0xc7, 0x30, 0xe6, 0x1e, 0x46, 0x96, 0x51, 0x3d, 0x77, 0xb5, 0xb4, 0x7e, 0x2d, 0x2d, 0xb6,
4385
+	0x27, 0x25, 0x6a, 0xd3, 0x0a, 0x63, 0x7e, 0x48, 0x13, 0x2d, 0xb9, 0x0d, 0x25, 0x8e, 0xd1, 0x28,
4386
+	0xc0, 0xde, 0x01, 0x67, 0xc1, 0x59, 0x1f, 0x8e, 0xbb, 0xc8, 0xc5, 0x68, 0xa3, 0xa0, 0xf8, 0xcf,
4387
+	0x38, 0x0b, 0xc8, 0x75, 0x20, 0x5e, 0xe8, 0xf8, 0x23, 0x17, 0x7b, 0xcc, 0x77, 0x7b, 0xea, 0x13,
4388
+	0x28, 0x9b, 0xb7, 0x40, 0x97, 0xf5, 0x93, 0x1d, 0xdf, 0x55, 0x43, 0xad, 0xfc, 0xad, 0x01, 0x70,
4389
+	0xec, 0x43, 0xea, 0xfc, 0xf9, 0x18, 0x4c, 0xdb, 0x89, 0xc5, 0xcc, 0xcd, 0xca, 0x82, 0x79, 0x6d,
4390
+	0xee, 0x4b, 0x6d, 0x48, 0xec, 0x8e, 0x17, 0xba, 0x54, 0x4b, 0xc8, 0x2d, 0xc8, 0x1f, 0x78, 0x7e,
4391
+	0x8c, 0x3c, 0xb2, 0xce, 0xc9, 0x90, 0x5c, 0x39, 0xab, 0x4d, 0x68, 0x02, 0xd7, 0x7e, 0x49, 0x62,
4392
+	0xbb, 0x85, 0x51, 0x64, 0xf7, 0x91, 0x7c, 0x0a, 0x26, 0x8e, 0x31, 0x8c, 0x93, 0xd0, 0xbe, 0x31,
4393
+	0xd7, 0x0b, 0xad, 0xa8, 0xb7, 0x04, 0x4e, 0xb5, 0x8a, 0xbc, 0x0f, 0xf9, 0xb1, 0x8a, 0xd6, 0x7f,
4394
+	0x09, 0x68, 0xc2, 0x96, 0x7f, 0x32, 0x60, 0x41, 0x1a, 0x3a, 0x11, 0x06, 0xe3, 0xe5, 0xc3, 0xb0,
4395
+	0x0e, 0xa6, 0x4e, 0x44, 0x76, 0xfe, 0xb7, 0x47, 0xa5, 0x84, 0x6a, 0x92, 0x7c, 0x08, 0x30, 0x93,
4396
+	0xc0, 0xb3, 0x75, 0x45, 0x96, 0x64, 0xf5, 0xad, 0x7f, 0x0c, 0xb8, 0x30, 0xe3, 0x0a, 0xb9, 0x09,
4397
+	0xab, 0xf7, 0x36, 0xf6, 0x9a, 0xed, 0xde, 0x46, 0x73, 0xaf, 0xb3, 0xb3, 0xdd, 0xdb, 0xdf, 0xbe,
4398
+	0xb3, 0xbd, 0x73, 0x6f, 0x7b, 0x39, 0x53, 0x2e, 0x3f, 0x7e, 0x52, 0xbd, 0x34, 0x83, 0xef, 0x87,
4399
+	0x83, 0x90, 0x3d, 0x14, 0x8e, 0xaf, 0x9c, 0x52, 0x35, 0x69, 0x6b, 0x63, 0xaf, 0xb5, 0x6c, 0x94,
4400
+	0xff, 0xf7, 0xf8, 0x49, 0xf5, 0xe2, 0x8c, 0xa8, 0xc9, 0x51, 0x4d, 0xa6, 0xd3, 0x9a, 0xfd, 0xdd,
4401
+	0x4d, 0xa1, 0xc9, 0xa6, 0x6a, 0xf6, 0x87, 0x6e, 0x9a, 0x86, 0xb6, 0xb6, 0x76, 0xee, 0xb6, 0x96,
4402
+	0x73, 0xa9, 0x1a, 0x8a, 0x01, 0x1b, 0x63, 0xf9, 0xf2, 0x37, 0xdf, 0x57, 0x32, 0x3f, 0xff, 0x50,
4403
+	0x99, 0x7d, 0xd5, 0xf5, 0x00, 0x16, 0xba, 0xe2, 0x7f, 0x22, 0x71, 0x61, 0x41, 0x3e, 0x23, 0xd5,
4404
+	0x17, 0x35, 0x62, 0xb9, 0xfa, 0xa2, 0x7a, 0xaa, 0x5d, 0xfc, 0xf5, 0xc7, 0xbf, 0xbf, 0xcb, 0x5e,
4405
+	0x80, 0x25, 0x49, 0xbc, 0x1d, 0xd8, 0xa1, 0xdd, 0x47, 0xfe, 0x8e, 0xd1, 0xb0, 0x9e, 0x3e, 0xab,
4406
+	0x64, 0x7e, 0x7f, 0x56, 0xc9, 0x7c, 0x35, 0xad, 0x18, 0x4f, 0xa7, 0x15, 0xe3, 0xb7, 0x69, 0xc5,
4407
+	0xf8, 0x73, 0x5a, 0x31, 0xee, 0x9b, 0xf2, 0x0f, 0xe4, 0x7b, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff,
4408
+	0x9d, 0xb1, 0x59, 0x21, 0xb7, 0x0a, 0x00, 0x00,
4407 4409
 }
... ...
@@ -18,6 +18,7 @@ message Object {
18 18
 		Secret secret = 6;
19 19
 		Resource resource = 7;
20 20
 		Extension extension = 8;
21
+		Config config = 9;
21 22
 	}
22 23
 }
23 24
 
... ...
@@ -60,6 +61,7 @@ message SelectBy {
60 60
 		// supported by: service, task
61 61
 		string referenced_network_id = 13 [(gogoproto.customname) = "ReferencedNetworkID"];
62 62
 		string referenced_secret_id = 14 [(gogoproto.customname) = "ReferencedSecretID"];
63
+		string referenced_config_id = 16 [(gogoproto.customname) = "ReferencedConfigID"];
63 64
 
64 65
 		// supported by: resource
65 66
 		string kind = 15;
... ...
@@ -29,6 +29,7 @@
29 29
 		PluginDescription
30 30
 		EngineDescription
31 31
 		NodeDescription
32
+		NodeTLSInfo
32 33
 		RaftMemberStatus
33 34
 		NodeStatus
34 35
 		Image
... ...
@@ -63,11 +64,14 @@
63 63
 		Certificate
64 64
 		EncryptionKey
65 65
 		ManagerStatus
66
+		FileTarget
66 67
 		SecretReference
68
+		ConfigReference
67 69
 		BlacklistedCertificate
68 70
 		HealthConfig
69 71
 		MaybeEncryptedRecord
70 72
 		RootRotation
73
+		Privileges
71 74
 		NodeSpec
72 75
 		ServiceSpec
73 76
 		ReplicatedService
... ...
@@ -80,6 +84,7 @@
80 80
 		NetworkSpec
81 81
 		ClusterSpec
82 82
 		SecretSpec
83
+		ConfigSpec
83 84
 		Meta
84 85
 		Node
85 86
 		Service
... ...
@@ -89,6 +94,7 @@
89 89
 		Network
90 90
 		Cluster
91 91
 		Secret
92
+		Config
92 93
 		Resource
93 94
 		Extension
94 95
 		GetNodeRequest
... ...
@@ -140,6 +146,16 @@
140 140
 		CreateSecretResponse
141 141
 		RemoveSecretRequest
142 142
 		RemoveSecretResponse
143
+		GetConfigRequest
144
+		GetConfigResponse
145
+		UpdateConfigRequest
146
+		UpdateConfigResponse
147
+		ListConfigsRequest
148
+		ListConfigsResponse
149
+		CreateConfigRequest
150
+		CreateConfigResponse
151
+		RemoveConfigRequest
152
+		RemoveConfigResponse
143 153
 		SessionRequest
144 154
 		SessionMessage
145 155
 		HeartbeatRequest
... ...
@@ -336,7 +352,7 @@ func (x RaftMemberStatus_Reachability) String() string {
336 336
 	return proto.EnumName(RaftMemberStatus_Reachability_name, int32(x))
337 337
 }
338 338
 func (RaftMemberStatus_Reachability) EnumDescriptor() ([]byte, []int) {
339
-	return fileDescriptorTypes, []int{9, 0}
339
+	return fileDescriptorTypes, []int{10, 0}
340 340
 }
341 341
 
342 342
 // TODO(aluzzardi) These should be using `gogoproto.enumvalue_customname`.
... ...
@@ -369,7 +385,7 @@ var NodeStatus_State_value = map[string]int32{
369 369
 func (x NodeStatus_State) String() string {
370 370
 	return proto.EnumName(NodeStatus_State_name, int32(x))
371 371
 }
372
-func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10, 0} }
372
+func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11, 0} }
373 373
 
374 374
 type Mount_MountType int32
375 375
 
... ...
@@ -393,7 +409,7 @@ var Mount_MountType_value = map[string]int32{
393 393
 func (x Mount_MountType) String() string {
394 394
 	return proto.EnumName(Mount_MountType_name, int32(x))
395 395
 }
396
-func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12, 0} }
396
+func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} }
397 397
 
398 398
 type Mount_BindOptions_MountPropagation int32
399 399
 
... ...
@@ -427,7 +443,7 @@ func (x Mount_BindOptions_MountPropagation) String() string {
427 427
 	return proto.EnumName(Mount_BindOptions_MountPropagation_name, int32(x))
428 428
 }
429 429
 func (Mount_BindOptions_MountPropagation) EnumDescriptor() ([]byte, []int) {
430
-	return fileDescriptorTypes, []int{12, 0, 0}
430
+	return fileDescriptorTypes, []int{13, 0, 0}
431 431
 }
432 432
 
433 433
 type RestartPolicy_RestartCondition int32
... ...
@@ -453,7 +469,7 @@ func (x RestartPolicy_RestartCondition) String() string {
453 453
 	return proto.EnumName(RestartPolicy_RestartCondition_name, int32(x))
454 454
 }
455 455
 func (RestartPolicy_RestartCondition) EnumDescriptor() ([]byte, []int) {
456
-	return fileDescriptorTypes, []int{13, 0}
456
+	return fileDescriptorTypes, []int{14, 0}
457 457
 }
458 458
 
459 459
 type UpdateConfig_FailureAction int32
... ...
@@ -479,7 +495,7 @@ func (x UpdateConfig_FailureAction) String() string {
479 479
 	return proto.EnumName(UpdateConfig_FailureAction_name, int32(x))
480 480
 }
481 481
 func (UpdateConfig_FailureAction) EnumDescriptor() ([]byte, []int) {
482
-	return fileDescriptorTypes, []int{14, 0}
482
+	return fileDescriptorTypes, []int{15, 0}
483 483
 }
484 484
 
485 485
 // UpdateOrder controls the order of operations when rolling out an
... ...
@@ -506,7 +522,7 @@ func (x UpdateConfig_UpdateOrder) String() string {
506 506
 	return proto.EnumName(UpdateConfig_UpdateOrder_name, int32(x))
507 507
 }
508 508
 func (UpdateConfig_UpdateOrder) EnumDescriptor() ([]byte, []int) {
509
-	return fileDescriptorTypes, []int{14, 1}
509
+	return fileDescriptorTypes, []int{15, 1}
510 510
 }
511 511
 
512 512
 type UpdateStatus_UpdateState int32
... ...
@@ -544,7 +560,7 @@ func (x UpdateStatus_UpdateState) String() string {
544 544
 	return proto.EnumName(UpdateStatus_UpdateState_name, int32(x))
545 545
 }
546 546
 func (UpdateStatus_UpdateState) EnumDescriptor() ([]byte, []int) {
547
-	return fileDescriptorTypes, []int{15, 0}
547
+	return fileDescriptorTypes, []int{16, 0}
548 548
 }
549 549
 
550 550
 // AddressFamily specifies the network address family that
... ...
@@ -572,7 +588,7 @@ func (x IPAMConfig_AddressFamily) String() string {
572 572
 	return proto.EnumName(IPAMConfig_AddressFamily_name, int32(x))
573 573
 }
574 574
 func (IPAMConfig_AddressFamily) EnumDescriptor() ([]byte, []int) {
575
-	return fileDescriptorTypes, []int{20, 0}
575
+	return fileDescriptorTypes, []int{21, 0}
576 576
 }
577 577
 
578 578
 type PortConfig_Protocol int32
... ...
@@ -594,7 +610,7 @@ var PortConfig_Protocol_value = map[string]int32{
594 594
 func (x PortConfig_Protocol) String() string {
595 595
 	return proto.EnumName(PortConfig_Protocol_name, int32(x))
596 596
 }
597
-func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21, 0} }
597
+func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22, 0} }
598 598
 
599 599
 // PublishMode controls how ports are published on the swarm.
600 600
 type PortConfig_PublishMode int32
... ...
@@ -622,7 +638,7 @@ func (x PortConfig_PublishMode) String() string {
622 622
 	return proto.EnumName(PortConfig_PublishMode_name, int32(x))
623 623
 }
624 624
 func (PortConfig_PublishMode) EnumDescriptor() ([]byte, []int) {
625
-	return fileDescriptorTypes, []int{21, 1}
625
+	return fileDescriptorTypes, []int{22, 1}
626 626
 }
627 627
 
628 628
 type IssuanceStatus_State int32
... ...
@@ -662,7 +678,7 @@ var IssuanceStatus_State_value = map[string]int32{
662 662
 func (x IssuanceStatus_State) String() string {
663 663
 	return proto.EnumName(IssuanceStatus_State_name, int32(x))
664 664
 }
665
-func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26, 0} }
665
+func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27, 0} }
666 666
 
667 667
 type ExternalCA_CAProtocol int32
668 668
 
... ...
@@ -681,7 +697,7 @@ func (x ExternalCA_CAProtocol) String() string {
681 681
 	return proto.EnumName(ExternalCA_CAProtocol_name, int32(x))
682 682
 }
683 683
 func (ExternalCA_CAProtocol) EnumDescriptor() ([]byte, []int) {
684
-	return fileDescriptorTypes, []int{28, 0}
684
+	return fileDescriptorTypes, []int{29, 0}
685 685
 }
686 686
 
687 687
 // Encryption algorithm that can implemented using this key
... ...
@@ -702,7 +718,7 @@ func (x EncryptionKey_Algorithm) String() string {
702 702
 	return proto.EnumName(EncryptionKey_Algorithm_name, int32(x))
703 703
 }
704 704
 func (EncryptionKey_Algorithm) EnumDescriptor() ([]byte, []int) {
705
-	return fileDescriptorTypes, []int{41, 0}
705
+	return fileDescriptorTypes, []int{42, 0}
706 706
 }
707 707
 
708 708
 type MaybeEncryptedRecord_Algorithm int32
... ...
@@ -725,7 +741,7 @@ func (x MaybeEncryptedRecord_Algorithm) String() string {
725 725
 	return proto.EnumName(MaybeEncryptedRecord_Algorithm_name, int32(x))
726 726
 }
727 727
 func (MaybeEncryptedRecord_Algorithm) EnumDescriptor() ([]byte, []int) {
728
-	return fileDescriptorTypes, []int{46, 0}
728
+	return fileDescriptorTypes, []int{49, 0}
729 729
 }
730 730
 
731 731
 // Version tracks the last time an object in the store was updated.
... ...
@@ -828,12 +844,26 @@ type NodeDescription struct {
828 828
 	Resources *Resources `protobuf:"bytes,3,opt,name=resources" json:"resources,omitempty"`
829 829
 	// Information about the Docker Engine on the node.
830 830
 	Engine *EngineDescription `protobuf:"bytes,4,opt,name=engine" json:"engine,omitempty"`
831
+	// Information on the node's TLS setup
832
+	TLSInfo *NodeTLSInfo `protobuf:"bytes,5,opt,name=tls_info,json=tlsInfo" json:"tls_info,omitempty"`
831 833
 }
832 834
 
833 835
 func (m *NodeDescription) Reset()                    { *m = NodeDescription{} }
834 836
 func (*NodeDescription) ProtoMessage()               {}
835 837
 func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} }
836 838
 
839
+type NodeTLSInfo struct {
840
+	// Information about which root certs the node trusts
841
+	TrustRoot []byte `protobuf:"bytes,1,opt,name=trust_root,json=trustRoot,proto3" json:"trust_root,omitempty"`
842
+	// Information about the node's current TLS certificate
843
+	CertIssuerSubject   []byte `protobuf:"bytes,2,opt,name=cert_issuer_subject,json=certIssuerSubject,proto3" json:"cert_issuer_subject,omitempty"`
844
+	CertIssuerPublicKey []byte `protobuf:"bytes,3,opt,name=cert_issuer_public_key,json=certIssuerPublicKey,proto3" json:"cert_issuer_public_key,omitempty"`
845
+}
846
+
847
+func (m *NodeTLSInfo) Reset()                    { *m = NodeTLSInfo{} }
848
+func (*NodeTLSInfo) ProtoMessage()               {}
849
+func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} }
850
+
837 851
 type RaftMemberStatus struct {
838 852
 	Leader       bool                          `protobuf:"varint,1,opt,name=leader,proto3" json:"leader,omitempty"`
839 853
 	Reachability RaftMemberStatus_Reachability `protobuf:"varint,2,opt,name=reachability,proto3,enum=docker.swarmkit.v1.RaftMemberStatus_Reachability" json:"reachability,omitempty"`
... ...
@@ -842,7 +872,7 @@ type RaftMemberStatus struct {
842 842
 
843 843
 func (m *RaftMemberStatus) Reset()                    { *m = RaftMemberStatus{} }
844 844
 func (*RaftMemberStatus) ProtoMessage()               {}
845
-func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} }
845
+func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} }
846 846
 
847 847
 type NodeStatus struct {
848 848
 	State   NodeStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.NodeStatus_State" json:"state,omitempty"`
... ...
@@ -853,7 +883,7 @@ type NodeStatus struct {
853 853
 
854 854
 func (m *NodeStatus) Reset()                    { *m = NodeStatus{} }
855 855
 func (*NodeStatus) ProtoMessage()               {}
856
-func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} }
856
+func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} }
857 857
 
858 858
 type Image struct {
859 859
 	// reference is a docker image reference. This can include a rpository, tag
... ...
@@ -864,7 +894,7 @@ type Image struct {
864 864
 
865 865
 func (m *Image) Reset()                    { *m = Image{} }
866 866
 func (*Image) ProtoMessage()               {}
867
-func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} }
867
+func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} }
868 868
 
869 869
 // Mount describes volume mounts for a container.
870 870
 //
... ...
@@ -899,7 +929,7 @@ type Mount struct {
899 899
 
900 900
 func (m *Mount) Reset()                    { *m = Mount{} }
901 901
 func (*Mount) ProtoMessage()               {}
902
-func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} }
902
+func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} }
903 903
 
904 904
 // BindOptions specifies options that are specific to a bind mount.
905 905
 type Mount_BindOptions struct {
... ...
@@ -909,7 +939,7 @@ type Mount_BindOptions struct {
909 909
 
910 910
 func (m *Mount_BindOptions) Reset()                    { *m = Mount_BindOptions{} }
911 911
 func (*Mount_BindOptions) ProtoMessage()               {}
912
-func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12, 0} }
912
+func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} }
913 913
 
914 914
 // VolumeOptions contains parameters for mounting the volume.
915 915
 type Mount_VolumeOptions struct {
... ...
@@ -926,7 +956,7 @@ type Mount_VolumeOptions struct {
926 926
 
927 927
 func (m *Mount_VolumeOptions) Reset()                    { *m = Mount_VolumeOptions{} }
928 928
 func (*Mount_VolumeOptions) ProtoMessage()               {}
929
-func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12, 1} }
929
+func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 1} }
930 930
 
931 931
 type Mount_TmpfsOptions struct {
932 932
 	// Size sets the size of the tmpfs, in bytes.
... ...
@@ -944,7 +974,7 @@ type Mount_TmpfsOptions struct {
944 944
 
945 945
 func (m *Mount_TmpfsOptions) Reset()                    { *m = Mount_TmpfsOptions{} }
946 946
 func (*Mount_TmpfsOptions) ProtoMessage()               {}
947
-func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12, 2} }
947
+func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 2} }
948 948
 
949 949
 type RestartPolicy struct {
950 950
 	Condition RestartPolicy_RestartCondition `protobuf:"varint,1,opt,name=condition,proto3,enum=docker.swarmkit.v1.RestartPolicy_RestartCondition" json:"condition,omitempty"`
... ...
@@ -962,7 +992,7 @@ type RestartPolicy struct {
962 962
 
963 963
 func (m *RestartPolicy) Reset()                    { *m = RestartPolicy{} }
964 964
 func (*RestartPolicy) ProtoMessage()               {}
965
-func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} }
965
+func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} }
966 966
 
967 967
 // UpdateConfig specifies the rate and policy of updates.
968 968
 // TODO(aluzzardi): Consider making this a oneof with RollingStrategy and LockstepStrategy.
... ...
@@ -1002,7 +1032,7 @@ type UpdateConfig struct {
1002 1002
 
1003 1003
 func (m *UpdateConfig) Reset()                    { *m = UpdateConfig{} }
1004 1004
 func (*UpdateConfig) ProtoMessage()               {}
1005
-func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} }
1005
+func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} }
1006 1006
 
1007 1007
 // UpdateStatus is the status of an update in progress.
1008 1008
 type UpdateStatus struct {
... ...
@@ -1026,7 +1056,7 @@ type UpdateStatus struct {
1026 1026
 
1027 1027
 func (m *UpdateStatus) Reset()                    { *m = UpdateStatus{} }
1028 1028
 func (*UpdateStatus) ProtoMessage()               {}
1029
-func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} }
1029
+func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} }
1030 1030
 
1031 1031
 // Container specific status.
1032 1032
 type ContainerStatus struct {
... ...
@@ -1037,7 +1067,7 @@ type ContainerStatus struct {
1037 1037
 
1038 1038
 func (m *ContainerStatus) Reset()                    { *m = ContainerStatus{} }
1039 1039
 func (*ContainerStatus) ProtoMessage()               {}
1040
-func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} }
1040
+func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} }
1041 1041
 
1042 1042
 // PortStatus specifies the actual allocated runtime state of a list
1043 1043
 // of port configs.
... ...
@@ -1047,7 +1077,7 @@ type PortStatus struct {
1047 1047
 
1048 1048
 func (m *PortStatus) Reset()                    { *m = PortStatus{} }
1049 1049
 func (*PortStatus) ProtoMessage()               {}
1050
-func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} }
1050
+func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} }
1051 1051
 
1052 1052
 type TaskStatus struct {
1053 1053
 	// Note: can't use stdtime because this field is nullable.
... ...
@@ -1084,7 +1114,7 @@ type TaskStatus struct {
1084 1084
 
1085 1085
 func (m *TaskStatus) Reset()                    { *m = TaskStatus{} }
1086 1086
 func (*TaskStatus) ProtoMessage()               {}
1087
-func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} }
1087
+func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} }
1088 1088
 
1089 1089
 type isTaskStatus_RuntimeStatus interface {
1090 1090
 	isTaskStatus_RuntimeStatus()
... ...
@@ -1186,7 +1216,7 @@ type NetworkAttachmentConfig struct {
1186 1186
 
1187 1187
 func (m *NetworkAttachmentConfig) Reset()                    { *m = NetworkAttachmentConfig{} }
1188 1188
 func (*NetworkAttachmentConfig) ProtoMessage()               {}
1189
-func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} }
1189
+func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} }
1190 1190
 
1191 1191
 // IPAMConfig specifies parameters for IP Address Management.
1192 1192
 type IPAMConfig struct {
... ...
@@ -1207,7 +1237,7 @@ type IPAMConfig struct {
1207 1207
 
1208 1208
 func (m *IPAMConfig) Reset()                    { *m = IPAMConfig{} }
1209 1209
 func (*IPAMConfig) ProtoMessage()               {}
1210
-func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} }
1210
+func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} }
1211 1211
 
1212 1212
 // PortConfig specifies an exposed port which can be
1213 1213
 // addressed using the given name. This can be later queried
... ...
@@ -1233,7 +1263,7 @@ type PortConfig struct {
1233 1233
 
1234 1234
 func (m *PortConfig) Reset()                    { *m = PortConfig{} }
1235 1235
 func (*PortConfig) ProtoMessage()               {}
1236
-func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} }
1236
+func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} }
1237 1237
 
1238 1238
 // Driver is a generic driver type to be used throughout the API. For now, a
1239 1239
 // driver is simply a name and set of options. The field contents depend on the
... ...
@@ -1246,7 +1276,7 @@ type Driver struct {
1246 1246
 
1247 1247
 func (m *Driver) Reset()                    { *m = Driver{} }
1248 1248
 func (*Driver) ProtoMessage()               {}
1249
-func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} }
1249
+func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} }
1250 1250
 
1251 1251
 type IPAMOptions struct {
1252 1252
 	Driver  *Driver       `protobuf:"bytes,1,opt,name=driver" json:"driver,omitempty"`
... ...
@@ -1255,7 +1285,7 @@ type IPAMOptions struct {
1255 1255
 
1256 1256
 func (m *IPAMOptions) Reset()                    { *m = IPAMOptions{} }
1257 1257
 func (*IPAMOptions) ProtoMessage()               {}
1258
-func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} }
1258
+func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} }
1259 1259
 
1260 1260
 // Peer should be used anywhere where we are describing a remote peer.
1261 1261
 type Peer struct {
... ...
@@ -1265,7 +1295,7 @@ type Peer struct {
1265 1265
 
1266 1266
 func (m *Peer) Reset()                    { *m = Peer{} }
1267 1267
 func (*Peer) ProtoMessage()               {}
1268
-func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} }
1268
+func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} }
1269 1269
 
1270 1270
 // WeightedPeer should be used anywhere where we are describing a remote peer
1271 1271
 // with a weight.
... ...
@@ -1276,7 +1306,7 @@ type WeightedPeer struct {
1276 1276
 
1277 1277
 func (m *WeightedPeer) Reset()                    { *m = WeightedPeer{} }
1278 1278
 func (*WeightedPeer) ProtoMessage()               {}
1279
-func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} }
1279
+func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} }
1280 1280
 
1281 1281
 type IssuanceStatus struct {
1282 1282
 	State IssuanceStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.IssuanceStatus_State" json:"state,omitempty"`
... ...
@@ -1288,7 +1318,7 @@ type IssuanceStatus struct {
1288 1288
 
1289 1289
 func (m *IssuanceStatus) Reset()                    { *m = IssuanceStatus{} }
1290 1290
 func (*IssuanceStatus) ProtoMessage()               {}
1291
-func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} }
1291
+func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} }
1292 1292
 
1293 1293
 type AcceptancePolicy struct {
1294 1294
 	Policies []*AcceptancePolicy_RoleAdmissionPolicy `protobuf:"bytes,1,rep,name=policies" json:"policies,omitempty"`
... ...
@@ -1296,7 +1326,7 @@ type AcceptancePolicy struct {
1296 1296
 
1297 1297
 func (m *AcceptancePolicy) Reset()                    { *m = AcceptancePolicy{} }
1298 1298
 func (*AcceptancePolicy) ProtoMessage()               {}
1299
-func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} }
1299
+func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} }
1300 1300
 
1301 1301
 type AcceptancePolicy_RoleAdmissionPolicy struct {
1302 1302
 	Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"`
... ...
@@ -1311,7 +1341,7 @@ type AcceptancePolicy_RoleAdmissionPolicy struct {
1311 1311
 func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset()      { *m = AcceptancePolicy_RoleAdmissionPolicy{} }
1312 1312
 func (*AcceptancePolicy_RoleAdmissionPolicy) ProtoMessage() {}
1313 1313
 func (*AcceptancePolicy_RoleAdmissionPolicy) Descriptor() ([]byte, []int) {
1314
-	return fileDescriptorTypes, []int{27, 0}
1314
+	return fileDescriptorTypes, []int{28, 0}
1315 1315
 }
1316 1316
 
1317 1317
 type AcceptancePolicy_RoleAdmissionPolicy_Secret struct {
... ...
@@ -1326,7 +1356,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Reset() {
1326 1326
 }
1327 1327
 func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) ProtoMessage() {}
1328 1328
 func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) Descriptor() ([]byte, []int) {
1329
-	return fileDescriptorTypes, []int{27, 0, 0}
1329
+	return fileDescriptorTypes, []int{28, 0, 0}
1330 1330
 }
1331 1331
 
1332 1332
 type ExternalCA struct {
... ...
@@ -1343,7 +1373,7 @@ type ExternalCA struct {
1343 1343
 
1344 1344
 func (m *ExternalCA) Reset()                    { *m = ExternalCA{} }
1345 1345
 func (*ExternalCA) ProtoMessage()               {}
1346
-func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} }
1346
+func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} }
1347 1347
 
1348 1348
 type CAConfig struct {
1349 1349
 	// NodeCertExpiry is the duration certificates should be issued for
... ...
@@ -1368,7 +1398,7 @@ type CAConfig struct {
1368 1368
 
1369 1369
 func (m *CAConfig) Reset()                    { *m = CAConfig{} }
1370 1370
 func (*CAConfig) ProtoMessage()               {}
1371
-func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} }
1371
+func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} }
1372 1372
 
1373 1373
 // OrchestrationConfig defines cluster-level orchestration settings.
1374 1374
 type OrchestrationConfig struct {
... ...
@@ -1379,7 +1409,7 @@ type OrchestrationConfig struct {
1379 1379
 
1380 1380
 func (m *OrchestrationConfig) Reset()                    { *m = OrchestrationConfig{} }
1381 1381
 func (*OrchestrationConfig) ProtoMessage()               {}
1382
-func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} }
1382
+func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} }
1383 1383
 
1384 1384
 // TaskDefaults specifies default values for task creation.
1385 1385
 type TaskDefaults struct {
... ...
@@ -1393,7 +1423,7 @@ type TaskDefaults struct {
1393 1393
 
1394 1394
 func (m *TaskDefaults) Reset()                    { *m = TaskDefaults{} }
1395 1395
 func (*TaskDefaults) ProtoMessage()               {}
1396
-func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} }
1396
+func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} }
1397 1397
 
1398 1398
 // DispatcherConfig defines cluster-level dispatcher settings.
1399 1399
 type DispatcherConfig struct {
... ...
@@ -1405,7 +1435,7 @@ type DispatcherConfig struct {
1405 1405
 
1406 1406
 func (m *DispatcherConfig) Reset()                    { *m = DispatcherConfig{} }
1407 1407
 func (*DispatcherConfig) ProtoMessage()               {}
1408
-func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} }
1408
+func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} }
1409 1409
 
1410 1410
 // RaftConfig defines raft settings for the cluster.
1411 1411
 type RaftConfig struct {
... ...
@@ -1427,7 +1457,7 @@ type RaftConfig struct {
1427 1427
 
1428 1428
 func (m *RaftConfig) Reset()                    { *m = RaftConfig{} }
1429 1429
 func (*RaftConfig) ProtoMessage()               {}
1430
-func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} }
1430
+func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} }
1431 1431
 
1432 1432
 type EncryptionConfig struct {
1433 1433
 	// AutoLockManagers specifies whether or not managers TLS keys and raft data
... ...
@@ -1438,7 +1468,7 @@ type EncryptionConfig struct {
1438 1438
 
1439 1439
 func (m *EncryptionConfig) Reset()                    { *m = EncryptionConfig{} }
1440 1440
 func (*EncryptionConfig) ProtoMessage()               {}
1441
-func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} }
1441
+func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} }
1442 1442
 
1443 1443
 type SpreadOver struct {
1444 1444
 	SpreadDescriptor string `protobuf:"bytes,1,opt,name=spread_descriptor,json=spreadDescriptor,proto3" json:"spread_descriptor,omitempty"`
... ...
@@ -1446,7 +1476,7 @@ type SpreadOver struct {
1446 1446
 
1447 1447
 func (m *SpreadOver) Reset()                    { *m = SpreadOver{} }
1448 1448
 func (*SpreadOver) ProtoMessage()               {}
1449
-func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} }
1449
+func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} }
1450 1450
 
1451 1451
 type PlacementPreference struct {
1452 1452
 	// Types that are valid to be assigned to Preference:
... ...
@@ -1456,7 +1486,7 @@ type PlacementPreference struct {
1456 1456
 
1457 1457
 func (m *PlacementPreference) Reset()                    { *m = PlacementPreference{} }
1458 1458
 func (*PlacementPreference) ProtoMessage()               {}
1459
-func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} }
1459
+func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} }
1460 1460
 
1461 1461
 type isPlacementPreference_Preference interface {
1462 1462
 	isPlacementPreference_Preference()
... ...
@@ -1551,7 +1581,7 @@ type Placement struct {
1551 1551
 
1552 1552
 func (m *Placement) Reset()                    { *m = Placement{} }
1553 1553
 func (*Placement) ProtoMessage()               {}
1554
-func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} }
1554
+func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} }
1555 1555
 
1556 1556
 // JoinToken contains the join tokens for workers and managers.
1557 1557
 type JoinTokens struct {
... ...
@@ -1563,7 +1593,7 @@ type JoinTokens struct {
1563 1563
 
1564 1564
 func (m *JoinTokens) Reset()                    { *m = JoinTokens{} }
1565 1565
 func (*JoinTokens) ProtoMessage()               {}
1566
-func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} }
1566
+func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} }
1567 1567
 
1568 1568
 type RootCA struct {
1569 1569
 	// CAKey is the root CA private key.
... ...
@@ -1584,7 +1614,7 @@ type RootCA struct {
1584 1584
 
1585 1585
 func (m *RootCA) Reset()                    { *m = RootCA{} }
1586 1586
 func (*RootCA) ProtoMessage()               {}
1587
-func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} }
1587
+func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} }
1588 1588
 
1589 1589
 type Certificate struct {
1590 1590
 	Role        NodeRole       `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"`
... ...
@@ -1597,7 +1627,7 @@ type Certificate struct {
1597 1597
 
1598 1598
 func (m *Certificate) Reset()                    { *m = Certificate{} }
1599 1599
 func (*Certificate) ProtoMessage()               {}
1600
-func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} }
1600
+func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} }
1601 1601
 
1602 1602
 // Symmetric keys to encrypt inter-agent communication.
1603 1603
 type EncryptionKey struct {
... ...
@@ -1613,7 +1643,7 @@ type EncryptionKey struct {
1613 1613
 
1614 1614
 func (m *EncryptionKey) Reset()                    { *m = EncryptionKey{} }
1615 1615
 func (*EncryptionKey) ProtoMessage()               {}
1616
-func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} }
1616
+func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} }
1617 1617
 
1618 1618
 // ManagerStatus provides informations about the state of a manager in the cluster.
1619 1619
 type ManagerStatus struct {
... ...
@@ -1630,7 +1660,23 @@ type ManagerStatus struct {
1630 1630
 
1631 1631
 func (m *ManagerStatus) Reset()                    { *m = ManagerStatus{} }
1632 1632
 func (*ManagerStatus) ProtoMessage()               {}
1633
-func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} }
1633
+func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} }
1634
+
1635
+// FileTarget represents a specific target that is backed by a file
1636
+type FileTarget struct {
1637
+	// Name represents the final filename in the filesystem
1638
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
1639
+	// UID represents the file UID
1640
+	UID string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
1641
+	// GID represents the file GID
1642
+	GID string `protobuf:"bytes,3,opt,name=gid,proto3" json:"gid,omitempty"`
1643
+	// Mode represents the FileMode of the file
1644
+	Mode os.FileMode `protobuf:"varint,4,opt,name=mode,proto3,customtype=os.FileMode" json:"mode"`
1645
+}
1646
+
1647
+func (m *FileTarget) Reset()                    { *m = FileTarget{} }
1648
+func (*FileTarget) ProtoMessage()               {}
1649
+func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} }
1634 1650
 
1635 1651
 // SecretReference is the linkage between a service and a secret that it uses.
1636 1652
 type SecretReference struct {
... ...
@@ -1650,7 +1696,7 @@ type SecretReference struct {
1650 1650
 
1651 1651
 func (m *SecretReference) Reset()                    { *m = SecretReference{} }
1652 1652
 func (*SecretReference) ProtoMessage()               {}
1653
-func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} }
1653
+func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} }
1654 1654
 
1655 1655
 type isSecretReference_Target interface {
1656 1656
 	isSecretReference_Target()
... ...
@@ -1659,7 +1705,7 @@ type isSecretReference_Target interface {
1659 1659
 }
1660 1660
 
1661 1661
 type SecretReference_File struct {
1662
-	File *SecretReference_FileTarget `protobuf:"bytes,3,opt,name=file,oneof"`
1662
+	File *FileTarget `protobuf:"bytes,3,opt,name=file,oneof"`
1663 1663
 }
1664 1664
 
1665 1665
 func (*SecretReference_File) isSecretReference_Target() {}
... ...
@@ -1671,7 +1717,7 @@ func (m *SecretReference) GetTarget() isSecretReference_Target {
1671 1671
 	return nil
1672 1672
 }
1673 1673
 
1674
-func (m *SecretReference) GetFile() *SecretReference_FileTarget {
1674
+func (m *SecretReference) GetFile() *FileTarget {
1675 1675
 	if x, ok := m.GetTarget().(*SecretReference_File); ok {
1676 1676
 		return x.File
1677 1677
 	}
... ...
@@ -1708,7 +1754,7 @@ func _SecretReference_OneofUnmarshaler(msg proto.Message, tag, wire int, b *prot
1708 1708
 		if wire != proto.WireBytes {
1709 1709
 			return true, proto.ErrInternalBadWireType
1710 1710
 		}
1711
-		msg := new(SecretReference_FileTarget)
1711
+		msg := new(FileTarget)
1712 1712
 		err := b.DecodeMessage(msg)
1713 1713
 		m.Target = &SecretReference_File{msg}
1714 1714
 		return true, err
... ...
@@ -1733,22 +1779,104 @@ func _SecretReference_OneofSizer(msg proto.Message) (n int) {
1733 1733
 	return n
1734 1734
 }
1735 1735
 
1736
-// FileTarget represents a specific target that is backed by a file
1737
-type SecretReference_FileTarget struct {
1738
-	// Name represents the final filename in the filesystem
1739
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
1740
-	// UID represents the file UID
1741
-	UID string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
1742
-	// GID represents the file GID
1743
-	GID string `protobuf:"bytes,3,opt,name=gid,proto3" json:"gid,omitempty"`
1744
-	// Mode represents the FileMode of the file
1745
-	Mode os.FileMode `protobuf:"varint,4,opt,name=mode,proto3,customtype=os.FileMode" json:"mode"`
1736
+// ConfigReference is the linkage between a service and a config that it uses.
1737
+type ConfigReference struct {
1738
+	// ConfigID represents the ID of the specific Config that we're
1739
+	// referencing.
1740
+	ConfigID string `protobuf:"bytes,1,opt,name=config_id,json=configId,proto3" json:"config_id,omitempty"`
1741
+	// ConfigName is the name of the config that this references, but this is just provided for
1742
+	// lookup/display purposes. The config in the reference will be identified by its ID.
1743
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
1744
+	// Target specifies how this secret should be exposed to the task.
1745
+	//
1746
+	// Types that are valid to be assigned to Target:
1747
+	//	*ConfigReference_File
1748
+	Target isConfigReference_Target `protobuf_oneof:"target"`
1746 1749
 }
1747 1750
 
1748
-func (m *SecretReference_FileTarget) Reset()      { *m = SecretReference_FileTarget{} }
1749
-func (*SecretReference_FileTarget) ProtoMessage() {}
1750
-func (*SecretReference_FileTarget) Descriptor() ([]byte, []int) {
1751
-	return fileDescriptorTypes, []int{43, 0}
1751
+func (m *ConfigReference) Reset()                    { *m = ConfigReference{} }
1752
+func (*ConfigReference) ProtoMessage()               {}
1753
+func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} }
1754
+
1755
+type isConfigReference_Target interface {
1756
+	isConfigReference_Target()
1757
+	MarshalTo([]byte) (int, error)
1758
+	Size() int
1759
+}
1760
+
1761
+type ConfigReference_File struct {
1762
+	File *FileTarget `protobuf:"bytes,3,opt,name=file,oneof"`
1763
+}
1764
+
1765
+func (*ConfigReference_File) isConfigReference_Target() {}
1766
+
1767
+func (m *ConfigReference) GetTarget() isConfigReference_Target {
1768
+	if m != nil {
1769
+		return m.Target
1770
+	}
1771
+	return nil
1772
+}
1773
+
1774
+func (m *ConfigReference) GetFile() *FileTarget {
1775
+	if x, ok := m.GetTarget().(*ConfigReference_File); ok {
1776
+		return x.File
1777
+	}
1778
+	return nil
1779
+}
1780
+
1781
+// XXX_OneofFuncs is for the internal use of the proto package.
1782
+func (*ConfigReference) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
1783
+	return _ConfigReference_OneofMarshaler, _ConfigReference_OneofUnmarshaler, _ConfigReference_OneofSizer, []interface{}{
1784
+		(*ConfigReference_File)(nil),
1785
+	}
1786
+}
1787
+
1788
+func _ConfigReference_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
1789
+	m := msg.(*ConfigReference)
1790
+	// target
1791
+	switch x := m.Target.(type) {
1792
+	case *ConfigReference_File:
1793
+		_ = b.EncodeVarint(3<<3 | proto.WireBytes)
1794
+		if err := b.EncodeMessage(x.File); err != nil {
1795
+			return err
1796
+		}
1797
+	case nil:
1798
+	default:
1799
+		return fmt.Errorf("ConfigReference.Target has unexpected type %T", x)
1800
+	}
1801
+	return nil
1802
+}
1803
+
1804
+func _ConfigReference_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
1805
+	m := msg.(*ConfigReference)
1806
+	switch tag {
1807
+	case 3: // target.file
1808
+		if wire != proto.WireBytes {
1809
+			return true, proto.ErrInternalBadWireType
1810
+		}
1811
+		msg := new(FileTarget)
1812
+		err := b.DecodeMessage(msg)
1813
+		m.Target = &ConfigReference_File{msg}
1814
+		return true, err
1815
+	default:
1816
+		return false, nil
1817
+	}
1818
+}
1819
+
1820
+func _ConfigReference_OneofSizer(msg proto.Message) (n int) {
1821
+	m := msg.(*ConfigReference)
1822
+	// target
1823
+	switch x := m.Target.(type) {
1824
+	case *ConfigReference_File:
1825
+		s := proto.Size(x.File)
1826
+		n += proto.SizeVarint(3<<3 | proto.WireBytes)
1827
+		n += proto.SizeVarint(uint64(s))
1828
+		n += s
1829
+	case nil:
1830
+	default:
1831
+		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
1832
+	}
1833
+	return n
1752 1834
 }
1753 1835
 
1754 1836
 // BlacklistedCertificate is a record for a blacklisted certificate. It does not
... ...
@@ -1762,7 +1890,7 @@ type BlacklistedCertificate struct {
1762 1762
 
1763 1763
 func (m *BlacklistedCertificate) Reset()                    { *m = BlacklistedCertificate{} }
1764 1764
 func (*BlacklistedCertificate) ProtoMessage()               {}
1765
-func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} }
1765
+func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} }
1766 1766
 
1767 1767
 // HealthConfig holds configuration settings for the HEALTHCHECK feature.
1768 1768
 type HealthConfig struct {
... ...
@@ -1792,7 +1920,7 @@ type HealthConfig struct {
1792 1792
 
1793 1793
 func (m *HealthConfig) Reset()                    { *m = HealthConfig{} }
1794 1794
 func (*HealthConfig) ProtoMessage()               {}
1795
-func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} }
1795
+func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} }
1796 1796
 
1797 1797
 type MaybeEncryptedRecord struct {
1798 1798
 	Algorithm MaybeEncryptedRecord_Algorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=docker.swarmkit.v1.MaybeEncryptedRecord_Algorithm" json:"algorithm,omitempty"`
... ...
@@ -1802,7 +1930,7 @@ type MaybeEncryptedRecord struct {
1802 1802
 
1803 1803
 func (m *MaybeEncryptedRecord) Reset()                    { *m = MaybeEncryptedRecord{} }
1804 1804
 func (*MaybeEncryptedRecord) ProtoMessage()               {}
1805
-func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} }
1805
+func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} }
1806 1806
 
1807 1807
 type RootRotation struct {
1808 1808
 	CACert []byte `protobuf:"bytes,1,opt,name=ca_cert,json=caCert,proto3" json:"ca_cert,omitempty"`
... ...
@@ -1813,7 +1941,149 @@ type RootRotation struct {
1813 1813
 
1814 1814
 func (m *RootRotation) Reset()                    { *m = RootRotation{} }
1815 1815
 func (*RootRotation) ProtoMessage()               {}
1816
-func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} }
1816
+func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} }
1817
+
1818
+// Privileges specifies security configuration/permissions.
1819
+type Privileges struct {
1820
+	CredentialSpec *Privileges_CredentialSpec `protobuf:"bytes,1,opt,name=credential_spec,json=credentialSpec" json:"credential_spec,omitempty"`
1821
+	SELinuxContext *Privileges_SELinuxContext `protobuf:"bytes,2,opt,name=selinux_context,json=selinuxContext" json:"selinux_context,omitempty"`
1822
+}
1823
+
1824
+func (m *Privileges) Reset()                    { *m = Privileges{} }
1825
+func (*Privileges) ProtoMessage()               {}
1826
+func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} }
1827
+
1828
+// CredentialSpec for managed service account (Windows only).
1829
+type Privileges_CredentialSpec struct {
1830
+	// Types that are valid to be assigned to Source:
1831
+	//	*Privileges_CredentialSpec_File
1832
+	//	*Privileges_CredentialSpec_Registry
1833
+	Source isPrivileges_CredentialSpec_Source `protobuf_oneof:"source"`
1834
+}
1835
+
1836
+func (m *Privileges_CredentialSpec) Reset()      { *m = Privileges_CredentialSpec{} }
1837
+func (*Privileges_CredentialSpec) ProtoMessage() {}
1838
+func (*Privileges_CredentialSpec) Descriptor() ([]byte, []int) {
1839
+	return fileDescriptorTypes, []int{51, 0}
1840
+}
1841
+
1842
+type isPrivileges_CredentialSpec_Source interface {
1843
+	isPrivileges_CredentialSpec_Source()
1844
+	MarshalTo([]byte) (int, error)
1845
+	Size() int
1846
+}
1847
+
1848
+type Privileges_CredentialSpec_File struct {
1849
+	File string `protobuf:"bytes,1,opt,name=file,proto3,oneof"`
1850
+}
1851
+type Privileges_CredentialSpec_Registry struct {
1852
+	Registry string `protobuf:"bytes,2,opt,name=registry,proto3,oneof"`
1853
+}
1854
+
1855
+func (*Privileges_CredentialSpec_File) isPrivileges_CredentialSpec_Source()     {}
1856
+func (*Privileges_CredentialSpec_Registry) isPrivileges_CredentialSpec_Source() {}
1857
+
1858
+func (m *Privileges_CredentialSpec) GetSource() isPrivileges_CredentialSpec_Source {
1859
+	if m != nil {
1860
+		return m.Source
1861
+	}
1862
+	return nil
1863
+}
1864
+
1865
+func (m *Privileges_CredentialSpec) GetFile() string {
1866
+	if x, ok := m.GetSource().(*Privileges_CredentialSpec_File); ok {
1867
+		return x.File
1868
+	}
1869
+	return ""
1870
+}
1871
+
1872
+func (m *Privileges_CredentialSpec) GetRegistry() string {
1873
+	if x, ok := m.GetSource().(*Privileges_CredentialSpec_Registry); ok {
1874
+		return x.Registry
1875
+	}
1876
+	return ""
1877
+}
1878
+
1879
+// XXX_OneofFuncs is for the internal use of the proto package.
1880
+func (*Privileges_CredentialSpec) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
1881
+	return _Privileges_CredentialSpec_OneofMarshaler, _Privileges_CredentialSpec_OneofUnmarshaler, _Privileges_CredentialSpec_OneofSizer, []interface{}{
1882
+		(*Privileges_CredentialSpec_File)(nil),
1883
+		(*Privileges_CredentialSpec_Registry)(nil),
1884
+	}
1885
+}
1886
+
1887
+func _Privileges_CredentialSpec_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
1888
+	m := msg.(*Privileges_CredentialSpec)
1889
+	// source
1890
+	switch x := m.Source.(type) {
1891
+	case *Privileges_CredentialSpec_File:
1892
+		_ = b.EncodeVarint(1<<3 | proto.WireBytes)
1893
+		_ = b.EncodeStringBytes(x.File)
1894
+	case *Privileges_CredentialSpec_Registry:
1895
+		_ = b.EncodeVarint(2<<3 | proto.WireBytes)
1896
+		_ = b.EncodeStringBytes(x.Registry)
1897
+	case nil:
1898
+	default:
1899
+		return fmt.Errorf("Privileges_CredentialSpec.Source has unexpected type %T", x)
1900
+	}
1901
+	return nil
1902
+}
1903
+
1904
+func _Privileges_CredentialSpec_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
1905
+	m := msg.(*Privileges_CredentialSpec)
1906
+	switch tag {
1907
+	case 1: // source.file
1908
+		if wire != proto.WireBytes {
1909
+			return true, proto.ErrInternalBadWireType
1910
+		}
1911
+		x, err := b.DecodeStringBytes()
1912
+		m.Source = &Privileges_CredentialSpec_File{x}
1913
+		return true, err
1914
+	case 2: // source.registry
1915
+		if wire != proto.WireBytes {
1916
+			return true, proto.ErrInternalBadWireType
1917
+		}
1918
+		x, err := b.DecodeStringBytes()
1919
+		m.Source = &Privileges_CredentialSpec_Registry{x}
1920
+		return true, err
1921
+	default:
1922
+		return false, nil
1923
+	}
1924
+}
1925
+
1926
+func _Privileges_CredentialSpec_OneofSizer(msg proto.Message) (n int) {
1927
+	m := msg.(*Privileges_CredentialSpec)
1928
+	// source
1929
+	switch x := m.Source.(type) {
1930
+	case *Privileges_CredentialSpec_File:
1931
+		n += proto.SizeVarint(1<<3 | proto.WireBytes)
1932
+		n += proto.SizeVarint(uint64(len(x.File)))
1933
+		n += len(x.File)
1934
+	case *Privileges_CredentialSpec_Registry:
1935
+		n += proto.SizeVarint(2<<3 | proto.WireBytes)
1936
+		n += proto.SizeVarint(uint64(len(x.Registry)))
1937
+		n += len(x.Registry)
1938
+	case nil:
1939
+	default:
1940
+		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
1941
+	}
1942
+	return n
1943
+}
1944
+
1945
+// SELinuxContext contains the SELinux labels for the container.
1946
+type Privileges_SELinuxContext struct {
1947
+	Disable bool   `protobuf:"varint,1,opt,name=disable,proto3" json:"disable,omitempty"`
1948
+	User    string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"`
1949
+	Role    string `protobuf:"bytes,3,opt,name=role,proto3" json:"role,omitempty"`
1950
+	Type    string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"`
1951
+	Level   string `protobuf:"bytes,5,opt,name=level,proto3" json:"level,omitempty"`
1952
+}
1953
+
1954
+func (m *Privileges_SELinuxContext) Reset()      { *m = Privileges_SELinuxContext{} }
1955
+func (*Privileges_SELinuxContext) ProtoMessage() {}
1956
+func (*Privileges_SELinuxContext) Descriptor() ([]byte, []int) {
1957
+	return fileDescriptorTypes, []int{51, 1}
1958
+}
1817 1959
 
1818 1960
 func init() {
1819 1961
 	proto.RegisterType((*Version)(nil), "docker.swarmkit.v1.Version")
... ...
@@ -1825,6 +2095,7 @@ func init() {
1825 1825
 	proto.RegisterType((*PluginDescription)(nil), "docker.swarmkit.v1.PluginDescription")
1826 1826
 	proto.RegisterType((*EngineDescription)(nil), "docker.swarmkit.v1.EngineDescription")
1827 1827
 	proto.RegisterType((*NodeDescription)(nil), "docker.swarmkit.v1.NodeDescription")
1828
+	proto.RegisterType((*NodeTLSInfo)(nil), "docker.swarmkit.v1.NodeTLSInfo")
1828 1829
 	proto.RegisterType((*RaftMemberStatus)(nil), "docker.swarmkit.v1.RaftMemberStatus")
1829 1830
 	proto.RegisterType((*NodeStatus)(nil), "docker.swarmkit.v1.NodeStatus")
1830 1831
 	proto.RegisterType((*Image)(nil), "docker.swarmkit.v1.Image")
... ...
@@ -1864,12 +2135,16 @@ func init() {
1864 1864
 	proto.RegisterType((*Certificate)(nil), "docker.swarmkit.v1.Certificate")
1865 1865
 	proto.RegisterType((*EncryptionKey)(nil), "docker.swarmkit.v1.EncryptionKey")
1866 1866
 	proto.RegisterType((*ManagerStatus)(nil), "docker.swarmkit.v1.ManagerStatus")
1867
+	proto.RegisterType((*FileTarget)(nil), "docker.swarmkit.v1.FileTarget")
1867 1868
 	proto.RegisterType((*SecretReference)(nil), "docker.swarmkit.v1.SecretReference")
1868
-	proto.RegisterType((*SecretReference_FileTarget)(nil), "docker.swarmkit.v1.SecretReference.FileTarget")
1869
+	proto.RegisterType((*ConfigReference)(nil), "docker.swarmkit.v1.ConfigReference")
1869 1870
 	proto.RegisterType((*BlacklistedCertificate)(nil), "docker.swarmkit.v1.BlacklistedCertificate")
1870 1871
 	proto.RegisterType((*HealthConfig)(nil), "docker.swarmkit.v1.HealthConfig")
1871 1872
 	proto.RegisterType((*MaybeEncryptedRecord)(nil), "docker.swarmkit.v1.MaybeEncryptedRecord")
1872 1873
 	proto.RegisterType((*RootRotation)(nil), "docker.swarmkit.v1.RootRotation")
1874
+	proto.RegisterType((*Privileges)(nil), "docker.swarmkit.v1.Privileges")
1875
+	proto.RegisterType((*Privileges_CredentialSpec)(nil), "docker.swarmkit.v1.Privileges.CredentialSpec")
1876
+	proto.RegisterType((*Privileges_SELinuxContext)(nil), "docker.swarmkit.v1.Privileges.SELinuxContext")
1873 1877
 	proto.RegisterEnum("docker.swarmkit.v1.TaskState", TaskState_name, TaskState_value)
1874 1878
 	proto.RegisterEnum("docker.swarmkit.v1.NodeRole", NodeRole_name, NodeRole_value)
1875 1879
 	proto.RegisterEnum("docker.swarmkit.v1.RaftMemberStatus_Reachability", RaftMemberStatus_Reachability_name, RaftMemberStatus_Reachability_value)
... ...
@@ -2070,6 +2345,37 @@ func (m *NodeDescription) CopyFrom(src interface{}) {
2070 2070
 		m.Engine = &EngineDescription{}
2071 2071
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.Engine, o.Engine)
2072 2072
 	}
2073
+	if o.TLSInfo != nil {
2074
+		m.TLSInfo = &NodeTLSInfo{}
2075
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.TLSInfo, o.TLSInfo)
2076
+	}
2077
+}
2078
+
2079
+func (m *NodeTLSInfo) Copy() *NodeTLSInfo {
2080
+	if m == nil {
2081
+		return nil
2082
+	}
2083
+	o := &NodeTLSInfo{}
2084
+	o.CopyFrom(m)
2085
+	return o
2086
+}
2087
+
2088
+func (m *NodeTLSInfo) CopyFrom(src interface{}) {
2089
+
2090
+	o := src.(*NodeTLSInfo)
2091
+	*m = *o
2092
+	if o.TrustRoot != nil {
2093
+		m.TrustRoot = make([]byte, len(o.TrustRoot))
2094
+		copy(m.TrustRoot, o.TrustRoot)
2095
+	}
2096
+	if o.CertIssuerSubject != nil {
2097
+		m.CertIssuerSubject = make([]byte, len(o.CertIssuerSubject))
2098
+		copy(m.CertIssuerSubject, o.CertIssuerSubject)
2099
+	}
2100
+	if o.CertIssuerPublicKey != nil {
2101
+		m.CertIssuerPublicKey = make([]byte, len(o.CertIssuerPublicKey))
2102
+		copy(m.CertIssuerPublicKey, o.CertIssuerPublicKey)
2103
+	}
2073 2104
 }
2074 2105
 
2075 2106
 func (m *RaftMemberStatus) Copy() *RaftMemberStatus {
... ...
@@ -2873,6 +3179,21 @@ func (m *ManagerStatus) CopyFrom(src interface{}) {
2873 2873
 	*m = *o
2874 2874
 }
2875 2875
 
2876
+func (m *FileTarget) Copy() *FileTarget {
2877
+	if m == nil {
2878
+		return nil
2879
+	}
2880
+	o := &FileTarget{}
2881
+	o.CopyFrom(m)
2882
+	return o
2883
+}
2884
+
2885
+func (m *FileTarget) CopyFrom(src interface{}) {
2886
+
2887
+	o := src.(*FileTarget)
2888
+	*m = *o
2889
+}
2890
+
2876 2891
 func (m *SecretReference) Copy() *SecretReference {
2877 2892
 	if m == nil {
2878 2893
 		return nil
... ...
@@ -2890,7 +3211,7 @@ func (m *SecretReference) CopyFrom(src interface{}) {
2890 2890
 		switch o.Target.(type) {
2891 2891
 		case *SecretReference_File:
2892 2892
 			v := SecretReference_File{
2893
-				File: &SecretReference_FileTarget{},
2893
+				File: &FileTarget{},
2894 2894
 			}
2895 2895
 			github_com_docker_swarmkit_api_deepcopy.Copy(v.File, o.GetFile())
2896 2896
 			m.Target = &v
... ...
@@ -2899,19 +3220,30 @@ func (m *SecretReference) CopyFrom(src interface{}) {
2899 2899
 
2900 2900
 }
2901 2901
 
2902
-func (m *SecretReference_FileTarget) Copy() *SecretReference_FileTarget {
2902
+func (m *ConfigReference) Copy() *ConfigReference {
2903 2903
 	if m == nil {
2904 2904
 		return nil
2905 2905
 	}
2906
-	o := &SecretReference_FileTarget{}
2906
+	o := &ConfigReference{}
2907 2907
 	o.CopyFrom(m)
2908 2908
 	return o
2909 2909
 }
2910 2910
 
2911
-func (m *SecretReference_FileTarget) CopyFrom(src interface{}) {
2911
+func (m *ConfigReference) CopyFrom(src interface{}) {
2912 2912
 
2913
-	o := src.(*SecretReference_FileTarget)
2913
+	o := src.(*ConfigReference)
2914 2914
 	*m = *o
2915
+	if o.Target != nil {
2916
+		switch o.Target.(type) {
2917
+		case *ConfigReference_File:
2918
+			v := ConfigReference_File{
2919
+				File: &FileTarget{},
2920
+			}
2921
+			github_com_docker_swarmkit_api_deepcopy.Copy(v.File, o.GetFile())
2922
+			m.Target = &v
2923
+		}
2924
+	}
2925
+
2915 2926
 }
2916 2927
 
2917 2928
 func (m *BlacklistedCertificate) Copy() *BlacklistedCertificate {
... ...
@@ -3015,6 +3347,74 @@ func (m *RootRotation) CopyFrom(src interface{}) {
3015 3015
 	}
3016 3016
 }
3017 3017
 
3018
+func (m *Privileges) Copy() *Privileges {
3019
+	if m == nil {
3020
+		return nil
3021
+	}
3022
+	o := &Privileges{}
3023
+	o.CopyFrom(m)
3024
+	return o
3025
+}
3026
+
3027
+func (m *Privileges) CopyFrom(src interface{}) {
3028
+
3029
+	o := src.(*Privileges)
3030
+	*m = *o
3031
+	if o.CredentialSpec != nil {
3032
+		m.CredentialSpec = &Privileges_CredentialSpec{}
3033
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.CredentialSpec, o.CredentialSpec)
3034
+	}
3035
+	if o.SELinuxContext != nil {
3036
+		m.SELinuxContext = &Privileges_SELinuxContext{}
3037
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.SELinuxContext, o.SELinuxContext)
3038
+	}
3039
+}
3040
+
3041
+func (m *Privileges_CredentialSpec) Copy() *Privileges_CredentialSpec {
3042
+	if m == nil {
3043
+		return nil
3044
+	}
3045
+	o := &Privileges_CredentialSpec{}
3046
+	o.CopyFrom(m)
3047
+	return o
3048
+}
3049
+
3050
+func (m *Privileges_CredentialSpec) CopyFrom(src interface{}) {
3051
+
3052
+	o := src.(*Privileges_CredentialSpec)
3053
+	*m = *o
3054
+	if o.Source != nil {
3055
+		switch o.Source.(type) {
3056
+		case *Privileges_CredentialSpec_File:
3057
+			v := Privileges_CredentialSpec_File{
3058
+				File: o.GetFile(),
3059
+			}
3060
+			m.Source = &v
3061
+		case *Privileges_CredentialSpec_Registry:
3062
+			v := Privileges_CredentialSpec_Registry{
3063
+				Registry: o.GetRegistry(),
3064
+			}
3065
+			m.Source = &v
3066
+		}
3067
+	}
3068
+
3069
+}
3070
+
3071
+func (m *Privileges_SELinuxContext) Copy() *Privileges_SELinuxContext {
3072
+	if m == nil {
3073
+		return nil
3074
+	}
3075
+	o := &Privileges_SELinuxContext{}
3076
+	o.CopyFrom(m)
3077
+	return o
3078
+}
3079
+
3080
+func (m *Privileges_SELinuxContext) CopyFrom(src interface{}) {
3081
+
3082
+	o := src.(*Privileges_SELinuxContext)
3083
+	*m = *o
3084
+}
3085
+
3018 3086
 func (m *Version) Marshal() (dAtA []byte, err error) {
3019 3087
 	size := m.Size()
3020 3088
 	dAtA = make([]byte, size)
... ...
@@ -3351,6 +3751,52 @@ func (m *NodeDescription) MarshalTo(dAtA []byte) (int, error) {
3351 3351
 		}
3352 3352
 		i += n5
3353 3353
 	}
3354
+	if m.TLSInfo != nil {
3355
+		dAtA[i] = 0x2a
3356
+		i++
3357
+		i = encodeVarintTypes(dAtA, i, uint64(m.TLSInfo.Size()))
3358
+		n6, err := m.TLSInfo.MarshalTo(dAtA[i:])
3359
+		if err != nil {
3360
+			return 0, err
3361
+		}
3362
+		i += n6
3363
+	}
3364
+	return i, nil
3365
+}
3366
+
3367
+func (m *NodeTLSInfo) Marshal() (dAtA []byte, err error) {
3368
+	size := m.Size()
3369
+	dAtA = make([]byte, size)
3370
+	n, err := m.MarshalTo(dAtA)
3371
+	if err != nil {
3372
+		return nil, err
3373
+	}
3374
+	return dAtA[:n], nil
3375
+}
3376
+
3377
+func (m *NodeTLSInfo) MarshalTo(dAtA []byte) (int, error) {
3378
+	var i int
3379
+	_ = i
3380
+	var l int
3381
+	_ = l
3382
+	if len(m.TrustRoot) > 0 {
3383
+		dAtA[i] = 0xa
3384
+		i++
3385
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.TrustRoot)))
3386
+		i += copy(dAtA[i:], m.TrustRoot)
3387
+	}
3388
+	if len(m.CertIssuerSubject) > 0 {
3389
+		dAtA[i] = 0x12
3390
+		i++
3391
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.CertIssuerSubject)))
3392
+		i += copy(dAtA[i:], m.CertIssuerSubject)
3393
+	}
3394
+	if len(m.CertIssuerPublicKey) > 0 {
3395
+		dAtA[i] = 0x1a
3396
+		i++
3397
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.CertIssuerPublicKey)))
3398
+		i += copy(dAtA[i:], m.CertIssuerPublicKey)
3399
+	}
3354 3400
 	return i, nil
3355 3401
 }
3356 3402
 
... ...
@@ -3498,31 +3944,31 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) {
3498 3498
 		dAtA[i] = 0x2a
3499 3499
 		i++
3500 3500
 		i = encodeVarintTypes(dAtA, i, uint64(m.BindOptions.Size()))
3501
-		n6, err := m.BindOptions.MarshalTo(dAtA[i:])
3501
+		n7, err := m.BindOptions.MarshalTo(dAtA[i:])
3502 3502
 		if err != nil {
3503 3503
 			return 0, err
3504 3504
 		}
3505
-		i += n6
3505
+		i += n7
3506 3506
 	}
3507 3507
 	if m.VolumeOptions != nil {
3508 3508
 		dAtA[i] = 0x32
3509 3509
 		i++
3510 3510
 		i = encodeVarintTypes(dAtA, i, uint64(m.VolumeOptions.Size()))
3511
-		n7, err := m.VolumeOptions.MarshalTo(dAtA[i:])
3511
+		n8, err := m.VolumeOptions.MarshalTo(dAtA[i:])
3512 3512
 		if err != nil {
3513 3513
 			return 0, err
3514 3514
 		}
3515
-		i += n7
3515
+		i += n8
3516 3516
 	}
3517 3517
 	if m.TmpfsOptions != nil {
3518 3518
 		dAtA[i] = 0x3a
3519 3519
 		i++
3520 3520
 		i = encodeVarintTypes(dAtA, i, uint64(m.TmpfsOptions.Size()))
3521
-		n8, err := m.TmpfsOptions.MarshalTo(dAtA[i:])
3521
+		n9, err := m.TmpfsOptions.MarshalTo(dAtA[i:])
3522 3522
 		if err != nil {
3523 3523
 			return 0, err
3524 3524
 		}
3525
-		i += n8
3525
+		i += n9
3526 3526
 	}
3527 3527
 	return i, nil
3528 3528
 }
... ...
@@ -3596,11 +4042,11 @@ func (m *Mount_VolumeOptions) MarshalTo(dAtA []byte) (int, error) {
3596 3596
 		dAtA[i] = 0x1a
3597 3597
 		i++
3598 3598
 		i = encodeVarintTypes(dAtA, i, uint64(m.DriverConfig.Size()))
3599
-		n9, err := m.DriverConfig.MarshalTo(dAtA[i:])
3599
+		n10, err := m.DriverConfig.MarshalTo(dAtA[i:])
3600 3600
 		if err != nil {
3601 3601
 			return 0, err
3602 3602
 		}
3603
-		i += n9
3603
+		i += n10
3604 3604
 	}
3605 3605
 	return i, nil
3606 3606
 }
... ...
@@ -3657,11 +4103,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) {
3657 3657
 		dAtA[i] = 0x12
3658 3658
 		i++
3659 3659
 		i = encodeVarintTypes(dAtA, i, uint64(m.Delay.Size()))
3660
-		n10, err := m.Delay.MarshalTo(dAtA[i:])
3660
+		n11, err := m.Delay.MarshalTo(dAtA[i:])
3661 3661
 		if err != nil {
3662 3662
 			return 0, err
3663 3663
 		}
3664
-		i += n10
3664
+		i += n11
3665 3665
 	}
3666 3666
 	if m.MaxAttempts != 0 {
3667 3667
 		dAtA[i] = 0x18
... ...
@@ -3672,11 +4118,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) {
3672 3672
 		dAtA[i] = 0x22
3673 3673
 		i++
3674 3674
 		i = encodeVarintTypes(dAtA, i, uint64(m.Window.Size()))
3675
-		n11, err := m.Window.MarshalTo(dAtA[i:])
3675
+		n12, err := m.Window.MarshalTo(dAtA[i:])
3676 3676
 		if err != nil {
3677 3677
 			return 0, err
3678 3678
 		}
3679
-		i += n11
3679
+		i += n12
3680 3680
 	}
3681 3681
 	return i, nil
3682 3682
 }
... ...
@@ -3704,11 +4150,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) {
3704 3704
 	dAtA[i] = 0x12
3705 3705
 	i++
3706 3706
 	i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.Delay)))
3707
-	n12, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:])
3707
+	n13, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:])
3708 3708
 	if err != nil {
3709 3709
 		return 0, err
3710 3710
 	}
3711
-	i += n12
3711
+	i += n13
3712 3712
 	if m.FailureAction != 0 {
3713 3713
 		dAtA[i] = 0x18
3714 3714
 		i++
... ...
@@ -3718,11 +4164,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) {
3718 3718
 		dAtA[i] = 0x22
3719 3719
 		i++
3720 3720
 		i = encodeVarintTypes(dAtA, i, uint64(m.Monitor.Size()))
3721
-		n13, err := m.Monitor.MarshalTo(dAtA[i:])
3721
+		n14, err := m.Monitor.MarshalTo(dAtA[i:])
3722 3722
 		if err != nil {
3723 3723
 			return 0, err
3724 3724
 		}
3725
-		i += n13
3725
+		i += n14
3726 3726
 	}
3727 3727
 	if m.MaxFailureRatio != 0 {
3728 3728
 		dAtA[i] = 0x2d
... ...
@@ -3761,21 +4207,21 @@ func (m *UpdateStatus) MarshalTo(dAtA []byte) (int, error) {
3761 3761
 		dAtA[i] = 0x12
3762 3762
 		i++
3763 3763
 		i = encodeVarintTypes(dAtA, i, uint64(m.StartedAt.Size()))
3764
-		n14, err := m.StartedAt.MarshalTo(dAtA[i:])
3764
+		n15, err := m.StartedAt.MarshalTo(dAtA[i:])
3765 3765
 		if err != nil {
3766 3766
 			return 0, err
3767 3767
 		}
3768
-		i += n14
3768
+		i += n15
3769 3769
 	}
3770 3770
 	if m.CompletedAt != nil {
3771 3771
 		dAtA[i] = 0x1a
3772 3772
 		i++
3773 3773
 		i = encodeVarintTypes(dAtA, i, uint64(m.CompletedAt.Size()))
3774
-		n15, err := m.CompletedAt.MarshalTo(dAtA[i:])
3774
+		n16, err := m.CompletedAt.MarshalTo(dAtA[i:])
3775 3775
 		if err != nil {
3776 3776
 			return 0, err
3777 3777
 		}
3778
-		i += n15
3778
+		i += n16
3779 3779
 	}
3780 3780
 	if len(m.Message) > 0 {
3781 3781
 		dAtA[i] = 0x22
... ...
@@ -3869,11 +4315,11 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) {
3869 3869
 		dAtA[i] = 0xa
3870 3870
 		i++
3871 3871
 		i = encodeVarintTypes(dAtA, i, uint64(m.Timestamp.Size()))
3872
-		n16, err := m.Timestamp.MarshalTo(dAtA[i:])
3872
+		n17, err := m.Timestamp.MarshalTo(dAtA[i:])
3873 3873
 		if err != nil {
3874 3874
 			return 0, err
3875 3875
 		}
3876
-		i += n16
3876
+		i += n17
3877 3877
 	}
3878 3878
 	if m.State != 0 {
3879 3879
 		dAtA[i] = 0x10
... ...
@@ -3893,21 +4339,21 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) {
3893 3893
 		i += copy(dAtA[i:], m.Err)
3894 3894
 	}
3895 3895
 	if m.RuntimeStatus != nil {
3896
-		nn17, err := m.RuntimeStatus.MarshalTo(dAtA[i:])
3896
+		nn18, err := m.RuntimeStatus.MarshalTo(dAtA[i:])
3897 3897
 		if err != nil {
3898 3898
 			return 0, err
3899 3899
 		}
3900
-		i += nn17
3900
+		i += nn18
3901 3901
 	}
3902 3902
 	if m.PortStatus != nil {
3903 3903
 		dAtA[i] = 0x32
3904 3904
 		i++
3905 3905
 		i = encodeVarintTypes(dAtA, i, uint64(m.PortStatus.Size()))
3906
-		n18, err := m.PortStatus.MarshalTo(dAtA[i:])
3906
+		n19, err := m.PortStatus.MarshalTo(dAtA[i:])
3907 3907
 		if err != nil {
3908 3908
 			return 0, err
3909 3909
 		}
3910
-		i += n18
3910
+		i += n19
3911 3911
 	}
3912 3912
 	return i, nil
3913 3913
 }
... ...
@@ -3918,11 +4364,11 @@ func (m *TaskStatus_Container) MarshalTo(dAtA []byte) (int, error) {
3918 3918
 		dAtA[i] = 0x2a
3919 3919
 		i++
3920 3920
 		i = encodeVarintTypes(dAtA, i, uint64(m.Container.Size()))
3921
-		n19, err := m.Container.MarshalTo(dAtA[i:])
3921
+		n20, err := m.Container.MarshalTo(dAtA[i:])
3922 3922
 		if err != nil {
3923 3923
 			return 0, err
3924 3924
 		}
3925
-		i += n19
3925
+		i += n20
3926 3926
 	}
3927 3927
 	return i, nil
3928 3928
 }
... ...
@@ -4142,11 +4588,11 @@ func (m *IPAMOptions) MarshalTo(dAtA []byte) (int, error) {
4142 4142
 		dAtA[i] = 0xa
4143 4143
 		i++
4144 4144
 		i = encodeVarintTypes(dAtA, i, uint64(m.Driver.Size()))
4145
-		n20, err := m.Driver.MarshalTo(dAtA[i:])
4145
+		n21, err := m.Driver.MarshalTo(dAtA[i:])
4146 4146
 		if err != nil {
4147 4147
 			return 0, err
4148 4148
 		}
4149
-		i += n20
4149
+		i += n21
4150 4150
 	}
4151 4151
 	if len(m.Configs) > 0 {
4152 4152
 		for _, msg := range m.Configs {
... ...
@@ -4212,11 +4658,11 @@ func (m *WeightedPeer) MarshalTo(dAtA []byte) (int, error) {
4212 4212
 		dAtA[i] = 0xa
4213 4213
 		i++
4214 4214
 		i = encodeVarintTypes(dAtA, i, uint64(m.Peer.Size()))
4215
-		n21, err := m.Peer.MarshalTo(dAtA[i:])
4215
+		n22, err := m.Peer.MarshalTo(dAtA[i:])
4216 4216
 		if err != nil {
4217 4217
 			return 0, err
4218 4218
 		}
4219
-		i += n21
4219
+		i += n22
4220 4220
 	}
4221 4221
 	if m.Weight != 0 {
4222 4222
 		dAtA[i] = 0x10
... ...
@@ -4319,11 +4765,11 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) MarshalTo(dAtA []byte) (int, erro
4319 4319
 		dAtA[i] = 0x1a
4320 4320
 		i++
4321 4321
 		i = encodeVarintTypes(dAtA, i, uint64(m.Secret.Size()))
4322
-		n22, err := m.Secret.MarshalTo(dAtA[i:])
4322
+		n23, err := m.Secret.MarshalTo(dAtA[i:])
4323 4323
 		if err != nil {
4324 4324
 			return 0, err
4325 4325
 		}
4326
-		i += n22
4326
+		i += n23
4327 4327
 	}
4328 4328
 	return i, nil
4329 4329
 }
... ...
@@ -4429,11 +4875,11 @@ func (m *CAConfig) MarshalTo(dAtA []byte) (int, error) {
4429 4429
 		dAtA[i] = 0xa
4430 4430
 		i++
4431 4431
 		i = encodeVarintTypes(dAtA, i, uint64(m.NodeCertExpiry.Size()))
4432
-		n23, err := m.NodeCertExpiry.MarshalTo(dAtA[i:])
4432
+		n24, err := m.NodeCertExpiry.MarshalTo(dAtA[i:])
4433 4433
 		if err != nil {
4434 4434
 			return 0, err
4435 4435
 		}
4436
-		i += n23
4436
+		i += n24
4437 4437
 	}
4438 4438
 	if len(m.ExternalCAs) > 0 {
4439 4439
 		for _, msg := range m.ExternalCAs {
... ...
@@ -4509,11 +4955,11 @@ func (m *TaskDefaults) MarshalTo(dAtA []byte) (int, error) {
4509 4509
 		dAtA[i] = 0xa
4510 4510
 		i++
4511 4511
 		i = encodeVarintTypes(dAtA, i, uint64(m.LogDriver.Size()))
4512
-		n24, err := m.LogDriver.MarshalTo(dAtA[i:])
4512
+		n25, err := m.LogDriver.MarshalTo(dAtA[i:])
4513 4513
 		if err != nil {
4514 4514
 			return 0, err
4515 4515
 		}
4516
-		i += n24
4516
+		i += n25
4517 4517
 	}
4518 4518
 	return i, nil
4519 4519
 }
... ...
@@ -4537,11 +4983,11 @@ func (m *DispatcherConfig) MarshalTo(dAtA []byte) (int, error) {
4537 4537
 		dAtA[i] = 0xa
4538 4538
 		i++
4539 4539
 		i = encodeVarintTypes(dAtA, i, uint64(m.HeartbeatPeriod.Size()))
4540
-		n25, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:])
4540
+		n26, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:])
4541 4541
 		if err != nil {
4542 4542
 			return 0, err
4543 4543
 		}
4544
-		i += n25
4544
+		i += n26
4545 4545
 	}
4546 4546
 	return i, nil
4547 4547
 }
... ...
@@ -4657,11 +5103,11 @@ func (m *PlacementPreference) MarshalTo(dAtA []byte) (int, error) {
4657 4657
 	var l int
4658 4658
 	_ = l
4659 4659
 	if m.Preference != nil {
4660
-		nn26, err := m.Preference.MarshalTo(dAtA[i:])
4660
+		nn27, err := m.Preference.MarshalTo(dAtA[i:])
4661 4661
 		if err != nil {
4662 4662
 			return 0, err
4663 4663
 		}
4664
-		i += nn26
4664
+		i += nn27
4665 4665
 	}
4666 4666
 	return i, nil
4667 4667
 }
... ...
@@ -4672,11 +5118,11 @@ func (m *PlacementPreference_Spread) MarshalTo(dAtA []byte) (int, error) {
4672 4672
 		dAtA[i] = 0xa
4673 4673
 		i++
4674 4674
 		i = encodeVarintTypes(dAtA, i, uint64(m.Spread.Size()))
4675
-		n27, err := m.Spread.MarshalTo(dAtA[i:])
4675
+		n28, err := m.Spread.MarshalTo(dAtA[i:])
4676 4676
 		if err != nil {
4677 4677
 			return 0, err
4678 4678
 		}
4679
-		i += n27
4679
+		i += n28
4680 4680
 	}
4681 4681
 	return i, nil
4682 4682
 }
... ...
@@ -4791,20 +5237,20 @@ func (m *RootCA) MarshalTo(dAtA []byte) (int, error) {
4791 4791
 	dAtA[i] = 0x22
4792 4792
 	i++
4793 4793
 	i = encodeVarintTypes(dAtA, i, uint64(m.JoinTokens.Size()))
4794
-	n28, err := m.JoinTokens.MarshalTo(dAtA[i:])
4794
+	n29, err := m.JoinTokens.MarshalTo(dAtA[i:])
4795 4795
 	if err != nil {
4796 4796
 		return 0, err
4797 4797
 	}
4798
-	i += n28
4798
+	i += n29
4799 4799
 	if m.RootRotation != nil {
4800 4800
 		dAtA[i] = 0x2a
4801 4801
 		i++
4802 4802
 		i = encodeVarintTypes(dAtA, i, uint64(m.RootRotation.Size()))
4803
-		n29, err := m.RootRotation.MarshalTo(dAtA[i:])
4803
+		n30, err := m.RootRotation.MarshalTo(dAtA[i:])
4804 4804
 		if err != nil {
4805 4805
 			return 0, err
4806 4806
 		}
4807
-		i += n29
4807
+		i += n30
4808 4808
 	}
4809 4809
 	if m.LastForcedRotation != 0 {
4810 4810
 		dAtA[i] = 0x30
... ...
@@ -4843,11 +5289,11 @@ func (m *Certificate) MarshalTo(dAtA []byte) (int, error) {
4843 4843
 	dAtA[i] = 0x1a
4844 4844
 	i++
4845 4845
 	i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size()))
4846
-	n30, err := m.Status.MarshalTo(dAtA[i:])
4846
+	n31, err := m.Status.MarshalTo(dAtA[i:])
4847 4847
 	if err != nil {
4848 4848
 		return 0, err
4849 4849
 	}
4850
-	i += n30
4850
+	i += n31
4851 4851
 	if len(m.Certificate) > 0 {
4852 4852
 		dAtA[i] = 0x22
4853 4853
 		i++
... ...
@@ -4947,6 +5393,47 @@ func (m *ManagerStatus) MarshalTo(dAtA []byte) (int, error) {
4947 4947
 	return i, nil
4948 4948
 }
4949 4949
 
4950
+func (m *FileTarget) Marshal() (dAtA []byte, err error) {
4951
+	size := m.Size()
4952
+	dAtA = make([]byte, size)
4953
+	n, err := m.MarshalTo(dAtA)
4954
+	if err != nil {
4955
+		return nil, err
4956
+	}
4957
+	return dAtA[:n], nil
4958
+}
4959
+
4960
+func (m *FileTarget) MarshalTo(dAtA []byte) (int, error) {
4961
+	var i int
4962
+	_ = i
4963
+	var l int
4964
+	_ = l
4965
+	if len(m.Name) > 0 {
4966
+		dAtA[i] = 0xa
4967
+		i++
4968
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.Name)))
4969
+		i += copy(dAtA[i:], m.Name)
4970
+	}
4971
+	if len(m.UID) > 0 {
4972
+		dAtA[i] = 0x12
4973
+		i++
4974
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.UID)))
4975
+		i += copy(dAtA[i:], m.UID)
4976
+	}
4977
+	if len(m.GID) > 0 {
4978
+		dAtA[i] = 0x1a
4979
+		i++
4980
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.GID)))
4981
+		i += copy(dAtA[i:], m.GID)
4982
+	}
4983
+	if m.Mode != 0 {
4984
+		dAtA[i] = 0x20
4985
+		i++
4986
+		i = encodeVarintTypes(dAtA, i, uint64(m.Mode))
4987
+	}
4988
+	return i, nil
4989
+}
4990
+
4950 4991
 func (m *SecretReference) Marshal() (dAtA []byte, err error) {
4951 4992
 	size := m.Size()
4952 4993
 	dAtA = make([]byte, size)
... ...
@@ -4975,11 +5462,11 @@ func (m *SecretReference) MarshalTo(dAtA []byte) (int, error) {
4975 4975
 		i += copy(dAtA[i:], m.SecretName)
4976 4976
 	}
4977 4977
 	if m.Target != nil {
4978
-		nn31, err := m.Target.MarshalTo(dAtA[i:])
4978
+		nn32, err := m.Target.MarshalTo(dAtA[i:])
4979 4979
 		if err != nil {
4980 4980
 			return 0, err
4981 4981
 		}
4982
-		i += nn31
4982
+		i += nn32
4983 4983
 	}
4984 4984
 	return i, nil
4985 4985
 }
... ...
@@ -4990,15 +5477,15 @@ func (m *SecretReference_File) MarshalTo(dAtA []byte) (int, error) {
4990 4990
 		dAtA[i] = 0x1a
4991 4991
 		i++
4992 4992
 		i = encodeVarintTypes(dAtA, i, uint64(m.File.Size()))
4993
-		n32, err := m.File.MarshalTo(dAtA[i:])
4993
+		n33, err := m.File.MarshalTo(dAtA[i:])
4994 4994
 		if err != nil {
4995 4995
 			return 0, err
4996 4996
 		}
4997
-		i += n32
4997
+		i += n33
4998 4998
 	}
4999 4999
 	return i, nil
5000 5000
 }
5001
-func (m *SecretReference_FileTarget) Marshal() (dAtA []byte, err error) {
5001
+func (m *ConfigReference) Marshal() (dAtA []byte, err error) {
5002 5002
 	size := m.Size()
5003 5003
 	dAtA = make([]byte, size)
5004 5004
 	n, err := m.MarshalTo(dAtA)
... ...
@@ -5008,37 +5495,47 @@ func (m *SecretReference_FileTarget) Marshal() (dAtA []byte, err error) {
5008 5008
 	return dAtA[:n], nil
5009 5009
 }
5010 5010
 
5011
-func (m *SecretReference_FileTarget) MarshalTo(dAtA []byte) (int, error) {
5011
+func (m *ConfigReference) MarshalTo(dAtA []byte) (int, error) {
5012 5012
 	var i int
5013 5013
 	_ = i
5014 5014
 	var l int
5015 5015
 	_ = l
5016
-	if len(m.Name) > 0 {
5016
+	if len(m.ConfigID) > 0 {
5017 5017
 		dAtA[i] = 0xa
5018 5018
 		i++
5019
-		i = encodeVarintTypes(dAtA, i, uint64(len(m.Name)))
5020
-		i += copy(dAtA[i:], m.Name)
5019
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.ConfigID)))
5020
+		i += copy(dAtA[i:], m.ConfigID)
5021 5021
 	}
5022
-	if len(m.UID) > 0 {
5022
+	if len(m.ConfigName) > 0 {
5023 5023
 		dAtA[i] = 0x12
5024 5024
 		i++
5025
-		i = encodeVarintTypes(dAtA, i, uint64(len(m.UID)))
5026
-		i += copy(dAtA[i:], m.UID)
5025
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.ConfigName)))
5026
+		i += copy(dAtA[i:], m.ConfigName)
5027 5027
 	}
5028
-	if len(m.GID) > 0 {
5029
-		dAtA[i] = 0x1a
5030
-		i++
5031
-		i = encodeVarintTypes(dAtA, i, uint64(len(m.GID)))
5032
-		i += copy(dAtA[i:], m.GID)
5028
+	if m.Target != nil {
5029
+		nn34, err := m.Target.MarshalTo(dAtA[i:])
5030
+		if err != nil {
5031
+			return 0, err
5032
+		}
5033
+		i += nn34
5033 5034
 	}
5034
-	if m.Mode != 0 {
5035
-		dAtA[i] = 0x20
5035
+	return i, nil
5036
+}
5037
+
5038
+func (m *ConfigReference_File) MarshalTo(dAtA []byte) (int, error) {
5039
+	i := 0
5040
+	if m.File != nil {
5041
+		dAtA[i] = 0x1a
5036 5042
 		i++
5037
-		i = encodeVarintTypes(dAtA, i, uint64(m.Mode))
5043
+		i = encodeVarintTypes(dAtA, i, uint64(m.File.Size()))
5044
+		n35, err := m.File.MarshalTo(dAtA[i:])
5045
+		if err != nil {
5046
+			return 0, err
5047
+		}
5048
+		i += n35
5038 5049
 	}
5039 5050
 	return i, nil
5040 5051
 }
5041
-
5042 5052
 func (m *BlacklistedCertificate) Marshal() (dAtA []byte, err error) {
5043 5053
 	size := m.Size()
5044 5054
 	dAtA = make([]byte, size)
... ...
@@ -5058,11 +5555,11 @@ func (m *BlacklistedCertificate) MarshalTo(dAtA []byte) (int, error) {
5058 5058
 		dAtA[i] = 0xa
5059 5059
 		i++
5060 5060
 		i = encodeVarintTypes(dAtA, i, uint64(m.Expiry.Size()))
5061
-		n33, err := m.Expiry.MarshalTo(dAtA[i:])
5061
+		n36, err := m.Expiry.MarshalTo(dAtA[i:])
5062 5062
 		if err != nil {
5063 5063
 			return 0, err
5064 5064
 		}
5065
-		i += n33
5065
+		i += n36
5066 5066
 	}
5067 5067
 	return i, nil
5068 5068
 }
... ...
@@ -5101,21 +5598,21 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) {
5101 5101
 		dAtA[i] = 0x12
5102 5102
 		i++
5103 5103
 		i = encodeVarintTypes(dAtA, i, uint64(m.Interval.Size()))
5104
-		n34, err := m.Interval.MarshalTo(dAtA[i:])
5104
+		n37, err := m.Interval.MarshalTo(dAtA[i:])
5105 5105
 		if err != nil {
5106 5106
 			return 0, err
5107 5107
 		}
5108
-		i += n34
5108
+		i += n37
5109 5109
 	}
5110 5110
 	if m.Timeout != nil {
5111 5111
 		dAtA[i] = 0x1a
5112 5112
 		i++
5113 5113
 		i = encodeVarintTypes(dAtA, i, uint64(m.Timeout.Size()))
5114
-		n35, err := m.Timeout.MarshalTo(dAtA[i:])
5114
+		n38, err := m.Timeout.MarshalTo(dAtA[i:])
5115 5115
 		if err != nil {
5116 5116
 			return 0, err
5117 5117
 		}
5118
-		i += n35
5118
+		i += n38
5119 5119
 	}
5120 5120
 	if m.Retries != 0 {
5121 5121
 		dAtA[i] = 0x20
... ...
@@ -5126,11 +5623,11 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) {
5126 5126
 		dAtA[i] = 0x2a
5127 5127
 		i++
5128 5128
 		i = encodeVarintTypes(dAtA, i, uint64(m.StartPeriod.Size()))
5129
-		n36, err := m.StartPeriod.MarshalTo(dAtA[i:])
5129
+		n39, err := m.StartPeriod.MarshalTo(dAtA[i:])
5130 5130
 		if err != nil {
5131 5131
 			return 0, err
5132 5132
 		}
5133
-		i += n36
5133
+		i += n39
5134 5134
 	}
5135 5135
 	return i, nil
5136 5136
 }
... ...
@@ -5206,6 +5703,137 @@ func (m *RootRotation) MarshalTo(dAtA []byte) (int, error) {
5206 5206
 	return i, nil
5207 5207
 }
5208 5208
 
5209
+func (m *Privileges) Marshal() (dAtA []byte, err error) {
5210
+	size := m.Size()
5211
+	dAtA = make([]byte, size)
5212
+	n, err := m.MarshalTo(dAtA)
5213
+	if err != nil {
5214
+		return nil, err
5215
+	}
5216
+	return dAtA[:n], nil
5217
+}
5218
+
5219
+func (m *Privileges) MarshalTo(dAtA []byte) (int, error) {
5220
+	var i int
5221
+	_ = i
5222
+	var l int
5223
+	_ = l
5224
+	if m.CredentialSpec != nil {
5225
+		dAtA[i] = 0xa
5226
+		i++
5227
+		i = encodeVarintTypes(dAtA, i, uint64(m.CredentialSpec.Size()))
5228
+		n40, err := m.CredentialSpec.MarshalTo(dAtA[i:])
5229
+		if err != nil {
5230
+			return 0, err
5231
+		}
5232
+		i += n40
5233
+	}
5234
+	if m.SELinuxContext != nil {
5235
+		dAtA[i] = 0x12
5236
+		i++
5237
+		i = encodeVarintTypes(dAtA, i, uint64(m.SELinuxContext.Size()))
5238
+		n41, err := m.SELinuxContext.MarshalTo(dAtA[i:])
5239
+		if err != nil {
5240
+			return 0, err
5241
+		}
5242
+		i += n41
5243
+	}
5244
+	return i, nil
5245
+}
5246
+
5247
+func (m *Privileges_CredentialSpec) Marshal() (dAtA []byte, err error) {
5248
+	size := m.Size()
5249
+	dAtA = make([]byte, size)
5250
+	n, err := m.MarshalTo(dAtA)
5251
+	if err != nil {
5252
+		return nil, err
5253
+	}
5254
+	return dAtA[:n], nil
5255
+}
5256
+
5257
+func (m *Privileges_CredentialSpec) MarshalTo(dAtA []byte) (int, error) {
5258
+	var i int
5259
+	_ = i
5260
+	var l int
5261
+	_ = l
5262
+	if m.Source != nil {
5263
+		nn42, err := m.Source.MarshalTo(dAtA[i:])
5264
+		if err != nil {
5265
+			return 0, err
5266
+		}
5267
+		i += nn42
5268
+	}
5269
+	return i, nil
5270
+}
5271
+
5272
+func (m *Privileges_CredentialSpec_File) MarshalTo(dAtA []byte) (int, error) {
5273
+	i := 0
5274
+	dAtA[i] = 0xa
5275
+	i++
5276
+	i = encodeVarintTypes(dAtA, i, uint64(len(m.File)))
5277
+	i += copy(dAtA[i:], m.File)
5278
+	return i, nil
5279
+}
5280
+func (m *Privileges_CredentialSpec_Registry) MarshalTo(dAtA []byte) (int, error) {
5281
+	i := 0
5282
+	dAtA[i] = 0x12
5283
+	i++
5284
+	i = encodeVarintTypes(dAtA, i, uint64(len(m.Registry)))
5285
+	i += copy(dAtA[i:], m.Registry)
5286
+	return i, nil
5287
+}
5288
+func (m *Privileges_SELinuxContext) Marshal() (dAtA []byte, err error) {
5289
+	size := m.Size()
5290
+	dAtA = make([]byte, size)
5291
+	n, err := m.MarshalTo(dAtA)
5292
+	if err != nil {
5293
+		return nil, err
5294
+	}
5295
+	return dAtA[:n], nil
5296
+}
5297
+
5298
+func (m *Privileges_SELinuxContext) MarshalTo(dAtA []byte) (int, error) {
5299
+	var i int
5300
+	_ = i
5301
+	var l int
5302
+	_ = l
5303
+	if m.Disable {
5304
+		dAtA[i] = 0x8
5305
+		i++
5306
+		if m.Disable {
5307
+			dAtA[i] = 1
5308
+		} else {
5309
+			dAtA[i] = 0
5310
+		}
5311
+		i++
5312
+	}
5313
+	if len(m.User) > 0 {
5314
+		dAtA[i] = 0x12
5315
+		i++
5316
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.User)))
5317
+		i += copy(dAtA[i:], m.User)
5318
+	}
5319
+	if len(m.Role) > 0 {
5320
+		dAtA[i] = 0x1a
5321
+		i++
5322
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.Role)))
5323
+		i += copy(dAtA[i:], m.Role)
5324
+	}
5325
+	if len(m.Type) > 0 {
5326
+		dAtA[i] = 0x22
5327
+		i++
5328
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.Type)))
5329
+		i += copy(dAtA[i:], m.Type)
5330
+	}
5331
+	if len(m.Level) > 0 {
5332
+		dAtA[i] = 0x2a
5333
+		i++
5334
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.Level)))
5335
+		i += copy(dAtA[i:], m.Level)
5336
+	}
5337
+	return i, nil
5338
+}
5339
+
5209 5340
 func encodeFixed64Types(dAtA []byte, offset int, v uint64) int {
5210 5341
 	dAtA[offset] = uint8(v)
5211 5342
 	dAtA[offset+1] = uint8(v >> 8)
... ...
@@ -5378,6 +6006,28 @@ func (m *NodeDescription) Size() (n int) {
5378 5378
 		l = m.Engine.Size()
5379 5379
 		n += 1 + l + sovTypes(uint64(l))
5380 5380
 	}
5381
+	if m.TLSInfo != nil {
5382
+		l = m.TLSInfo.Size()
5383
+		n += 1 + l + sovTypes(uint64(l))
5384
+	}
5385
+	return n
5386
+}
5387
+
5388
+func (m *NodeTLSInfo) Size() (n int) {
5389
+	var l int
5390
+	_ = l
5391
+	l = len(m.TrustRoot)
5392
+	if l > 0 {
5393
+		n += 1 + l + sovTypes(uint64(l))
5394
+	}
5395
+	l = len(m.CertIssuerSubject)
5396
+	if l > 0 {
5397
+		n += 1 + l + sovTypes(uint64(l))
5398
+	}
5399
+	l = len(m.CertIssuerPublicKey)
5400
+	if l > 0 {
5401
+		n += 1 + l + sovTypes(uint64(l))
5402
+	}
5381 5403
 	return n
5382 5404
 }
5383 5405
 
... ...
@@ -6077,6 +6727,27 @@ func (m *ManagerStatus) Size() (n int) {
6077 6077
 	return n
6078 6078
 }
6079 6079
 
6080
+func (m *FileTarget) Size() (n int) {
6081
+	var l int
6082
+	_ = l
6083
+	l = len(m.Name)
6084
+	if l > 0 {
6085
+		n += 1 + l + sovTypes(uint64(l))
6086
+	}
6087
+	l = len(m.UID)
6088
+	if l > 0 {
6089
+		n += 1 + l + sovTypes(uint64(l))
6090
+	}
6091
+	l = len(m.GID)
6092
+	if l > 0 {
6093
+		n += 1 + l + sovTypes(uint64(l))
6094
+	}
6095
+	if m.Mode != 0 {
6096
+		n += 1 + sovTypes(uint64(m.Mode))
6097
+	}
6098
+	return n
6099
+}
6100
+
6080 6101
 func (m *SecretReference) Size() (n int) {
6081 6102
 	var l int
6082 6103
 	_ = l
... ...
@@ -6103,27 +6774,32 @@ func (m *SecretReference_File) Size() (n int) {
6103 6103
 	}
6104 6104
 	return n
6105 6105
 }
6106
-func (m *SecretReference_FileTarget) Size() (n int) {
6106
+func (m *ConfigReference) Size() (n int) {
6107 6107
 	var l int
6108 6108
 	_ = l
6109
-	l = len(m.Name)
6109
+	l = len(m.ConfigID)
6110 6110
 	if l > 0 {
6111 6111
 		n += 1 + l + sovTypes(uint64(l))
6112 6112
 	}
6113
-	l = len(m.UID)
6113
+	l = len(m.ConfigName)
6114 6114
 	if l > 0 {
6115 6115
 		n += 1 + l + sovTypes(uint64(l))
6116 6116
 	}
6117
-	l = len(m.GID)
6118
-	if l > 0 {
6119
-		n += 1 + l + sovTypes(uint64(l))
6120
-	}
6121
-	if m.Mode != 0 {
6122
-		n += 1 + sovTypes(uint64(m.Mode))
6117
+	if m.Target != nil {
6118
+		n += m.Target.Size()
6123 6119
 	}
6124 6120
 	return n
6125 6121
 }
6126 6122
 
6123
+func (m *ConfigReference_File) Size() (n int) {
6124
+	var l int
6125
+	_ = l
6126
+	if m.File != nil {
6127
+		l = m.File.Size()
6128
+		n += 1 + l + sovTypes(uint64(l))
6129
+	}
6130
+	return n
6131
+}
6127 6132
 func (m *BlacklistedCertificate) Size() (n int) {
6128 6133
 	var l int
6129 6134
 	_ = l
... ...
@@ -6196,6 +6872,68 @@ func (m *RootRotation) Size() (n int) {
6196 6196
 	return n
6197 6197
 }
6198 6198
 
6199
+func (m *Privileges) Size() (n int) {
6200
+	var l int
6201
+	_ = l
6202
+	if m.CredentialSpec != nil {
6203
+		l = m.CredentialSpec.Size()
6204
+		n += 1 + l + sovTypes(uint64(l))
6205
+	}
6206
+	if m.SELinuxContext != nil {
6207
+		l = m.SELinuxContext.Size()
6208
+		n += 1 + l + sovTypes(uint64(l))
6209
+	}
6210
+	return n
6211
+}
6212
+
6213
+func (m *Privileges_CredentialSpec) Size() (n int) {
6214
+	var l int
6215
+	_ = l
6216
+	if m.Source != nil {
6217
+		n += m.Source.Size()
6218
+	}
6219
+	return n
6220
+}
6221
+
6222
+func (m *Privileges_CredentialSpec_File) Size() (n int) {
6223
+	var l int
6224
+	_ = l
6225
+	l = len(m.File)
6226
+	n += 1 + l + sovTypes(uint64(l))
6227
+	return n
6228
+}
6229
+func (m *Privileges_CredentialSpec_Registry) Size() (n int) {
6230
+	var l int
6231
+	_ = l
6232
+	l = len(m.Registry)
6233
+	n += 1 + l + sovTypes(uint64(l))
6234
+	return n
6235
+}
6236
+func (m *Privileges_SELinuxContext) Size() (n int) {
6237
+	var l int
6238
+	_ = l
6239
+	if m.Disable {
6240
+		n += 2
6241
+	}
6242
+	l = len(m.User)
6243
+	if l > 0 {
6244
+		n += 1 + l + sovTypes(uint64(l))
6245
+	}
6246
+	l = len(m.Role)
6247
+	if l > 0 {
6248
+		n += 1 + l + sovTypes(uint64(l))
6249
+	}
6250
+	l = len(m.Type)
6251
+	if l > 0 {
6252
+		n += 1 + l + sovTypes(uint64(l))
6253
+	}
6254
+	l = len(m.Level)
6255
+	if l > 0 {
6256
+		n += 1 + l + sovTypes(uint64(l))
6257
+	}
6258
+	return n
6259
+}
6260
+
6199 6261
 func sovTypes(x uint64) (n int) {
6200 6262
 	for {
6201 6263
 		n++
... ...
@@ -6327,6 +7065,19 @@ func (this *NodeDescription) String() string {
6327 6327
 		`Platform:` + strings.Replace(fmt.Sprintf("%v", this.Platform), "Platform", "Platform", 1) + `,`,
6328 6328
 		`Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resources", "Resources", 1) + `,`,
6329 6329
 		`Engine:` + strings.Replace(fmt.Sprintf("%v", this.Engine), "EngineDescription", "EngineDescription", 1) + `,`,
6330
+		`TLSInfo:` + strings.Replace(fmt.Sprintf("%v", this.TLSInfo), "NodeTLSInfo", "NodeTLSInfo", 1) + `,`,
6331
+		`}`,
6332
+	}, "")
6333
+	return s
6334
+}
6335
+func (this *NodeTLSInfo) String() string {
6336
+	if this == nil {
6337
+		return "nil"
6338
+	}
6339
+	s := strings.Join([]string{`&NodeTLSInfo{`,
6340
+		`TrustRoot:` + fmt.Sprintf("%v", this.TrustRoot) + `,`,
6341
+		`CertIssuerSubject:` + fmt.Sprintf("%v", this.CertIssuerSubject) + `,`,
6342
+		`CertIssuerPublicKey:` + fmt.Sprintf("%v", this.CertIssuerPublicKey) + `,`,
6330 6343
 		`}`,
6331 6344
 	}, "")
6332 6345
 	return s
... ...
@@ -6858,6 +7609,19 @@ func (this *ManagerStatus) String() string {
6858 6858
 	}, "")
6859 6859
 	return s
6860 6860
 }
6861
+func (this *FileTarget) String() string {
6862
+	if this == nil {
6863
+		return "nil"
6864
+	}
6865
+	s := strings.Join([]string{`&FileTarget{`,
6866
+		`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
6867
+		`UID:` + fmt.Sprintf("%v", this.UID) + `,`,
6868
+		`GID:` + fmt.Sprintf("%v", this.GID) + `,`,
6869
+		`Mode:` + fmt.Sprintf("%v", this.Mode) + `,`,
6870
+		`}`,
6871
+	}, "")
6872
+	return s
6873
+}
6861 6874
 func (this *SecretReference) String() string {
6862 6875
 	if this == nil {
6863 6876
 		return "nil"
... ...
@@ -6875,20 +7639,29 @@ func (this *SecretReference_File) String() string {
6875 6875
 		return "nil"
6876 6876
 	}
6877 6877
 	s := strings.Join([]string{`&SecretReference_File{`,
6878
-		`File:` + strings.Replace(fmt.Sprintf("%v", this.File), "SecretReference_FileTarget", "SecretReference_FileTarget", 1) + `,`,
6878
+		`File:` + strings.Replace(fmt.Sprintf("%v", this.File), "FileTarget", "FileTarget", 1) + `,`,
6879 6879
 		`}`,
6880 6880
 	}, "")
6881 6881
 	return s
6882 6882
 }
6883
-func (this *SecretReference_FileTarget) String() string {
6883
+func (this *ConfigReference) String() string {
6884 6884
 	if this == nil {
6885 6885
 		return "nil"
6886 6886
 	}
6887
-	s := strings.Join([]string{`&SecretReference_FileTarget{`,
6888
-		`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
6889
-		`UID:` + fmt.Sprintf("%v", this.UID) + `,`,
6890
-		`GID:` + fmt.Sprintf("%v", this.GID) + `,`,
6891
-		`Mode:` + fmt.Sprintf("%v", this.Mode) + `,`,
6887
+	s := strings.Join([]string{`&ConfigReference{`,
6888
+		`ConfigID:` + fmt.Sprintf("%v", this.ConfigID) + `,`,
6889
+		`ConfigName:` + fmt.Sprintf("%v", this.ConfigName) + `,`,
6890
+		`Target:` + fmt.Sprintf("%v", this.Target) + `,`,
6891
+		`}`,
6892
+	}, "")
6893
+	return s
6894
+}
6895
+func (this *ConfigReference_File) String() string {
6896
+	if this == nil {
6897
+		return "nil"
6898
+	}
6899
+	s := strings.Join([]string{`&ConfigReference_File{`,
6900
+		`File:` + strings.Replace(fmt.Sprintf("%v", this.File), "FileTarget", "FileTarget", 1) + `,`,
6892 6901
 		`}`,
6893 6902
 	}, "")
6894 6903
 	return s
... ...
@@ -6941,6 +7714,61 @@ func (this *RootRotation) String() string {
6941 6941
 	}, "")
6942 6942
 	return s
6943 6943
 }
6944
+func (this *Privileges) String() string {
6945
+	if this == nil {
6946
+		return "nil"
6947
+	}
6948
+	s := strings.Join([]string{`&Privileges{`,
6949
+		`CredentialSpec:` + strings.Replace(fmt.Sprintf("%v", this.CredentialSpec), "Privileges_CredentialSpec", "Privileges_CredentialSpec", 1) + `,`,
6950
+		`SELinuxContext:` + strings.Replace(fmt.Sprintf("%v", this.SELinuxContext), "Privileges_SELinuxContext", "Privileges_SELinuxContext", 1) + `,`,
6951
+		`}`,
6952
+	}, "")
6953
+	return s
6954
+}
6955
+func (this *Privileges_CredentialSpec) String() string {
6956
+	if this == nil {
6957
+		return "nil"
6958
+	}
6959
+	s := strings.Join([]string{`&Privileges_CredentialSpec{`,
6960
+		`Source:` + fmt.Sprintf("%v", this.Source) + `,`,
6961
+		`}`,
6962
+	}, "")
6963
+	return s
6964
+}
6965
+func (this *Privileges_CredentialSpec_File) String() string {
6966
+	if this == nil {
6967
+		return "nil"
6968
+	}
6969
+	s := strings.Join([]string{`&Privileges_CredentialSpec_File{`,
6970
+		`File:` + fmt.Sprintf("%v", this.File) + `,`,
6971
+		`}`,
6972
+	}, "")
6973
+	return s
6974
+}
6975
+func (this *Privileges_CredentialSpec_Registry) String() string {
6976
+	if this == nil {
6977
+		return "nil"
6978
+	}
6979
+	s := strings.Join([]string{`&Privileges_CredentialSpec_Registry{`,
6980
+		`Registry:` + fmt.Sprintf("%v", this.Registry) + `,`,
6981
+		`}`,
6982
+	}, "")
6983
+	return s
6984
+}
6985
+func (this *Privileges_SELinuxContext) String() string {
6986
+	if this == nil {
6987
+		return "nil"
6988
+	}
6989
+	s := strings.Join([]string{`&Privileges_SELinuxContext{`,
6990
+		`Disable:` + fmt.Sprintf("%v", this.Disable) + `,`,
6991
+		`User:` + fmt.Sprintf("%v", this.User) + `,`,
6992
+		`Role:` + fmt.Sprintf("%v", this.Role) + `,`,
6993
+		`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
6994
+		`Level:` + fmt.Sprintf("%v", this.Level) + `,`,
6995
+		`}`,
6996
+	}, "")
6997
+	return s
6998
+}
6944 6999
 func valueToStringTypes(v interface{}) string {
6945 7000
 	rv := reflect.ValueOf(v)
6946 7001
 	if rv.IsNil() {
... ...
@@ -8155,6 +8983,182 @@ func (m *NodeDescription) Unmarshal(dAtA []byte) error {
8155 8155
 				return err
8156 8156
 			}
8157 8157
 			iNdEx = postIndex
8158
+		case 5:
8159
+			if wireType != 2 {
8160
+				return fmt.Errorf("proto: wrong wireType = %d for field TLSInfo", wireType)
8161
+			}
8162
+			var msglen int
8163
+			for shift := uint(0); ; shift += 7 {
8164
+				if shift >= 64 {
8165
+					return ErrIntOverflowTypes
8166
+				}
8167
+				if iNdEx >= l {
8168
+					return io.ErrUnexpectedEOF
8169
+				}
8170
+				b := dAtA[iNdEx]
8171
+				iNdEx++
8172
+				msglen |= (int(b) & 0x7F) << shift
8173
+				if b < 0x80 {
8174
+					break
8175
+				}
8176
+			}
8177
+			if msglen < 0 {
8178
+				return ErrInvalidLengthTypes
8179
+			}
8180
+			postIndex := iNdEx + msglen
8181
+			if postIndex > l {
8182
+				return io.ErrUnexpectedEOF
8183
+			}
8184
+			if m.TLSInfo == nil {
8185
+				m.TLSInfo = &NodeTLSInfo{}
8186
+			}
8187
+			if err := m.TLSInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
8188
+				return err
8189
+			}
8190
+			iNdEx = postIndex
8191
+		default:
8192
+			iNdEx = preIndex
8193
+			skippy, err := skipTypes(dAtA[iNdEx:])
8194
+			if err != nil {
8195
+				return err
8196
+			}
8197
+			if skippy < 0 {
8198
+				return ErrInvalidLengthTypes
8199
+			}
8200
+			if (iNdEx + skippy) > l {
8201
+				return io.ErrUnexpectedEOF
8202
+			}
8203
+			iNdEx += skippy
8204
+		}
8205
+	}
8206
+
8207
+	if iNdEx > l {
8208
+		return io.ErrUnexpectedEOF
8209
+	}
8210
+	return nil
8211
+}
8212
+func (m *NodeTLSInfo) Unmarshal(dAtA []byte) error {
8213
+	l := len(dAtA)
8214
+	iNdEx := 0
8215
+	for iNdEx < l {
8216
+		preIndex := iNdEx
8217
+		var wire uint64
8218
+		for shift := uint(0); ; shift += 7 {
8219
+			if shift >= 64 {
8220
+				return ErrIntOverflowTypes
8221
+			}
8222
+			if iNdEx >= l {
8223
+				return io.ErrUnexpectedEOF
8224
+			}
8225
+			b := dAtA[iNdEx]
8226
+			iNdEx++
8227
+			wire |= (uint64(b) & 0x7F) << shift
8228
+			if b < 0x80 {
8229
+				break
8230
+			}
8231
+		}
8232
+		fieldNum := int32(wire >> 3)
8233
+		wireType := int(wire & 0x7)
8234
+		if wireType == 4 {
8235
+			return fmt.Errorf("proto: NodeTLSInfo: wiretype end group for non-group")
8236
+		}
8237
+		if fieldNum <= 0 {
8238
+			return fmt.Errorf("proto: NodeTLSInfo: illegal tag %d (wire type %d)", fieldNum, wire)
8239
+		}
8240
+		switch fieldNum {
8241
+		case 1:
8242
+			if wireType != 2 {
8243
+				return fmt.Errorf("proto: wrong wireType = %d for field TrustRoot", wireType)
8244
+			}
8245
+			var byteLen int
8246
+			for shift := uint(0); ; shift += 7 {
8247
+				if shift >= 64 {
8248
+					return ErrIntOverflowTypes
8249
+				}
8250
+				if iNdEx >= l {
8251
+					return io.ErrUnexpectedEOF
8252
+				}
8253
+				b := dAtA[iNdEx]
8254
+				iNdEx++
8255
+				byteLen |= (int(b) & 0x7F) << shift
8256
+				if b < 0x80 {
8257
+					break
8258
+				}
8259
+			}
8260
+			if byteLen < 0 {
8261
+				return ErrInvalidLengthTypes
8262
+			}
8263
+			postIndex := iNdEx + byteLen
8264
+			if postIndex > l {
8265
+				return io.ErrUnexpectedEOF
8266
+			}
8267
+			m.TrustRoot = append(m.TrustRoot[:0], dAtA[iNdEx:postIndex]...)
8268
+			if m.TrustRoot == nil {
8269
+				m.TrustRoot = []byte{}
8270
+			}
8271
+			iNdEx = postIndex
8272
+		case 2:
8273
+			if wireType != 2 {
8274
+				return fmt.Errorf("proto: wrong wireType = %d for field CertIssuerSubject", wireType)
8275
+			}
8276
+			var byteLen int
8277
+			for shift := uint(0); ; shift += 7 {
8278
+				if shift >= 64 {
8279
+					return ErrIntOverflowTypes
8280
+				}
8281
+				if iNdEx >= l {
8282
+					return io.ErrUnexpectedEOF
8283
+				}
8284
+				b := dAtA[iNdEx]
8285
+				iNdEx++
8286
+				byteLen |= (int(b) & 0x7F) << shift
8287
+				if b < 0x80 {
8288
+					break
8289
+				}
8290
+			}
8291
+			if byteLen < 0 {
8292
+				return ErrInvalidLengthTypes
8293
+			}
8294
+			postIndex := iNdEx + byteLen
8295
+			if postIndex > l {
8296
+				return io.ErrUnexpectedEOF
8297
+			}
8298
+			m.CertIssuerSubject = append(m.CertIssuerSubject[:0], dAtA[iNdEx:postIndex]...)
8299
+			if m.CertIssuerSubject == nil {
8300
+				m.CertIssuerSubject = []byte{}
8301
+			}
8302
+			iNdEx = postIndex
8303
+		case 3:
8304
+			if wireType != 2 {
8305
+				return fmt.Errorf("proto: wrong wireType = %d for field CertIssuerPublicKey", wireType)
8306
+			}
8307
+			var byteLen int
8308
+			for shift := uint(0); ; shift += 7 {
8309
+				if shift >= 64 {
8310
+					return ErrIntOverflowTypes
8311
+				}
8312
+				if iNdEx >= l {
8313
+					return io.ErrUnexpectedEOF
8314
+				}
8315
+				b := dAtA[iNdEx]
8316
+				iNdEx++
8317
+				byteLen |= (int(b) & 0x7F) << shift
8318
+				if b < 0x80 {
8319
+					break
8320
+				}
8321
+			}
8322
+			if byteLen < 0 {
8323
+				return ErrInvalidLengthTypes
8324
+			}
8325
+			postIndex := iNdEx + byteLen
8326
+			if postIndex > l {
8327
+				return io.ErrUnexpectedEOF
8328
+			}
8329
+			m.CertIssuerPublicKey = append(m.CertIssuerPublicKey[:0], dAtA[iNdEx:postIndex]...)
8330
+			if m.CertIssuerPublicKey == nil {
8331
+				m.CertIssuerPublicKey = []byte{}
8332
+			}
8333
+			iNdEx = postIndex
8158 8334
 		default:
8159 8335
 			iNdEx = preIndex
8160 8336
 			skippy, err := skipTypes(dAtA[iNdEx:])
... ...
@@ -13508,7 +14512,7 @@ func (m *ManagerStatus) Unmarshal(dAtA []byte) error {
13508 13508
 	}
13509 13509
 	return nil
13510 13510
 }
13511
-func (m *SecretReference) Unmarshal(dAtA []byte) error {
13511
+func (m *FileTarget) Unmarshal(dAtA []byte) error {
13512 13512
 	l := len(dAtA)
13513 13513
 	iNdEx := 0
13514 13514
 	for iNdEx < l {
... ...
@@ -13531,15 +14535,15 @@ func (m *SecretReference) Unmarshal(dAtA []byte) error {
13531 13531
 		fieldNum := int32(wire >> 3)
13532 13532
 		wireType := int(wire & 0x7)
13533 13533
 		if wireType == 4 {
13534
-			return fmt.Errorf("proto: SecretReference: wiretype end group for non-group")
13534
+			return fmt.Errorf("proto: FileTarget: wiretype end group for non-group")
13535 13535
 		}
13536 13536
 		if fieldNum <= 0 {
13537
-			return fmt.Errorf("proto: SecretReference: illegal tag %d (wire type %d)", fieldNum, wire)
13537
+			return fmt.Errorf("proto: FileTarget: illegal tag %d (wire type %d)", fieldNum, wire)
13538 13538
 		}
13539 13539
 		switch fieldNum {
13540 13540
 		case 1:
13541 13541
 			if wireType != 2 {
13542
-				return fmt.Errorf("proto: wrong wireType = %d for field SecretID", wireType)
13542
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
13543 13543
 			}
13544 13544
 			var stringLen uint64
13545 13545
 			for shift := uint(0); ; shift += 7 {
... ...
@@ -13564,11 +14568,11 @@ func (m *SecretReference) Unmarshal(dAtA []byte) error {
13564 13564
 			if postIndex > l {
13565 13565
 				return io.ErrUnexpectedEOF
13566 13566
 			}
13567
-			m.SecretID = string(dAtA[iNdEx:postIndex])
13567
+			m.Name = string(dAtA[iNdEx:postIndex])
13568 13568
 			iNdEx = postIndex
13569 13569
 		case 2:
13570 13570
 			if wireType != 2 {
13571
-				return fmt.Errorf("proto: wrong wireType = %d for field SecretName", wireType)
13571
+				return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType)
13572 13572
 			}
13573 13573
 			var stringLen uint64
13574 13574
 			for shift := uint(0); ; shift += 7 {
... ...
@@ -13593,13 +14597,13 @@ func (m *SecretReference) Unmarshal(dAtA []byte) error {
13593 13593
 			if postIndex > l {
13594 13594
 				return io.ErrUnexpectedEOF
13595 13595
 			}
13596
-			m.SecretName = string(dAtA[iNdEx:postIndex])
13596
+			m.UID = string(dAtA[iNdEx:postIndex])
13597 13597
 			iNdEx = postIndex
13598 13598
 		case 3:
13599 13599
 			if wireType != 2 {
13600
-				return fmt.Errorf("proto: wrong wireType = %d for field File", wireType)
13600
+				return fmt.Errorf("proto: wrong wireType = %d for field GID", wireType)
13601 13601
 			}
13602
-			var msglen int
13602
+			var stringLen uint64
13603 13603
 			for shift := uint(0); ; shift += 7 {
13604 13604
 				if shift >= 64 {
13605 13605
 					return ErrIntOverflowTypes
... ...
@@ -13609,24 +14613,40 @@ func (m *SecretReference) Unmarshal(dAtA []byte) error {
13609 13609
 				}
13610 13610
 				b := dAtA[iNdEx]
13611 13611
 				iNdEx++
13612
-				msglen |= (int(b) & 0x7F) << shift
13612
+				stringLen |= (uint64(b) & 0x7F) << shift
13613 13613
 				if b < 0x80 {
13614 13614
 					break
13615 13615
 				}
13616 13616
 			}
13617
-			if msglen < 0 {
13617
+			intStringLen := int(stringLen)
13618
+			if intStringLen < 0 {
13618 13619
 				return ErrInvalidLengthTypes
13619 13620
 			}
13620
-			postIndex := iNdEx + msglen
13621
+			postIndex := iNdEx + intStringLen
13621 13622
 			if postIndex > l {
13622 13623
 				return io.ErrUnexpectedEOF
13623 13624
 			}
13624
-			v := &SecretReference_FileTarget{}
13625
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13626
-				return err
13627
-			}
13628
-			m.Target = &SecretReference_File{v}
13625
+			m.GID = string(dAtA[iNdEx:postIndex])
13629 13626
 			iNdEx = postIndex
13627
+		case 4:
13628
+			if wireType != 0 {
13629
+				return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType)
13630
+			}
13631
+			m.Mode = 0
13632
+			for shift := uint(0); ; shift += 7 {
13633
+				if shift >= 64 {
13634
+					return ErrIntOverflowTypes
13635
+				}
13636
+				if iNdEx >= l {
13637
+					return io.ErrUnexpectedEOF
13638
+				}
13639
+				b := dAtA[iNdEx]
13640
+				iNdEx++
13641
+				m.Mode |= (os.FileMode(b) & 0x7F) << shift
13642
+				if b < 0x80 {
13643
+					break
13644
+				}
13645
+			}
13630 13646
 		default:
13631 13647
 			iNdEx = preIndex
13632 13648
 			skippy, err := skipTypes(dAtA[iNdEx:])
... ...
@@ -13648,7 +14668,7 @@ func (m *SecretReference) Unmarshal(dAtA []byte) error {
13648 13648
 	}
13649 13649
 	return nil
13650 13650
 }
13651
-func (m *SecretReference_FileTarget) Unmarshal(dAtA []byte) error {
13651
+func (m *SecretReference) Unmarshal(dAtA []byte) error {
13652 13652
 	l := len(dAtA)
13653 13653
 	iNdEx := 0
13654 13654
 	for iNdEx < l {
... ...
@@ -13671,15 +14691,15 @@ func (m *SecretReference_FileTarget) Unmarshal(dAtA []byte) error {
13671 13671
 		fieldNum := int32(wire >> 3)
13672 13672
 		wireType := int(wire & 0x7)
13673 13673
 		if wireType == 4 {
13674
-			return fmt.Errorf("proto: FileTarget: wiretype end group for non-group")
13674
+			return fmt.Errorf("proto: SecretReference: wiretype end group for non-group")
13675 13675
 		}
13676 13676
 		if fieldNum <= 0 {
13677
-			return fmt.Errorf("proto: FileTarget: illegal tag %d (wire type %d)", fieldNum, wire)
13677
+			return fmt.Errorf("proto: SecretReference: illegal tag %d (wire type %d)", fieldNum, wire)
13678 13678
 		}
13679 13679
 		switch fieldNum {
13680 13680
 		case 1:
13681 13681
 			if wireType != 2 {
13682
-				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
13682
+				return fmt.Errorf("proto: wrong wireType = %d for field SecretID", wireType)
13683 13683
 			}
13684 13684
 			var stringLen uint64
13685 13685
 			for shift := uint(0); ; shift += 7 {
... ...
@@ -13704,11 +14724,11 @@ func (m *SecretReference_FileTarget) Unmarshal(dAtA []byte) error {
13704 13704
 			if postIndex > l {
13705 13705
 				return io.ErrUnexpectedEOF
13706 13706
 			}
13707
-			m.Name = string(dAtA[iNdEx:postIndex])
13707
+			m.SecretID = string(dAtA[iNdEx:postIndex])
13708 13708
 			iNdEx = postIndex
13709 13709
 		case 2:
13710 13710
 			if wireType != 2 {
13711
-				return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType)
13711
+				return fmt.Errorf("proto: wrong wireType = %d for field SecretName", wireType)
13712 13712
 			}
13713 13713
 			var stringLen uint64
13714 13714
 			for shift := uint(0); ; shift += 7 {
... ...
@@ -13733,11 +14753,93 @@ func (m *SecretReference_FileTarget) Unmarshal(dAtA []byte) error {
13733 13733
 			if postIndex > l {
13734 13734
 				return io.ErrUnexpectedEOF
13735 13735
 			}
13736
-			m.UID = string(dAtA[iNdEx:postIndex])
13736
+			m.SecretName = string(dAtA[iNdEx:postIndex])
13737 13737
 			iNdEx = postIndex
13738 13738
 		case 3:
13739 13739
 			if wireType != 2 {
13740
-				return fmt.Errorf("proto: wrong wireType = %d for field GID", wireType)
13740
+				return fmt.Errorf("proto: wrong wireType = %d for field File", wireType)
13741
+			}
13742
+			var msglen int
13743
+			for shift := uint(0); ; shift += 7 {
13744
+				if shift >= 64 {
13745
+					return ErrIntOverflowTypes
13746
+				}
13747
+				if iNdEx >= l {
13748
+					return io.ErrUnexpectedEOF
13749
+				}
13750
+				b := dAtA[iNdEx]
13751
+				iNdEx++
13752
+				msglen |= (int(b) & 0x7F) << shift
13753
+				if b < 0x80 {
13754
+					break
13755
+				}
13756
+			}
13757
+			if msglen < 0 {
13758
+				return ErrInvalidLengthTypes
13759
+			}
13760
+			postIndex := iNdEx + msglen
13761
+			if postIndex > l {
13762
+				return io.ErrUnexpectedEOF
13763
+			}
13764
+			v := &FileTarget{}
13765
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13766
+				return err
13767
+			}
13768
+			m.Target = &SecretReference_File{v}
13769
+			iNdEx = postIndex
13770
+		default:
13771
+			iNdEx = preIndex
13772
+			skippy, err := skipTypes(dAtA[iNdEx:])
13773
+			if err != nil {
13774
+				return err
13775
+			}
13776
+			if skippy < 0 {
13777
+				return ErrInvalidLengthTypes
13778
+			}
13779
+			if (iNdEx + skippy) > l {
13780
+				return io.ErrUnexpectedEOF
13781
+			}
13782
+			iNdEx += skippy
13783
+		}
13784
+	}
13785
+
13786
+	if iNdEx > l {
13787
+		return io.ErrUnexpectedEOF
13788
+	}
13789
+	return nil
13790
+}
13791
+func (m *ConfigReference) Unmarshal(dAtA []byte) error {
13792
+	l := len(dAtA)
13793
+	iNdEx := 0
13794
+	for iNdEx < l {
13795
+		preIndex := iNdEx
13796
+		var wire uint64
13797
+		for shift := uint(0); ; shift += 7 {
13798
+			if shift >= 64 {
13799
+				return ErrIntOverflowTypes
13800
+			}
13801
+			if iNdEx >= l {
13802
+				return io.ErrUnexpectedEOF
13803
+			}
13804
+			b := dAtA[iNdEx]
13805
+			iNdEx++
13806
+			wire |= (uint64(b) & 0x7F) << shift
13807
+			if b < 0x80 {
13808
+				break
13809
+			}
13810
+		}
13811
+		fieldNum := int32(wire >> 3)
13812
+		wireType := int(wire & 0x7)
13813
+		if wireType == 4 {
13814
+			return fmt.Errorf("proto: ConfigReference: wiretype end group for non-group")
13815
+		}
13816
+		if fieldNum <= 0 {
13817
+			return fmt.Errorf("proto: ConfigReference: illegal tag %d (wire type %d)", fieldNum, wire)
13818
+		}
13819
+		switch fieldNum {
13820
+		case 1:
13821
+			if wireType != 2 {
13822
+				return fmt.Errorf("proto: wrong wireType = %d for field ConfigID", wireType)
13741 13823
 			}
13742 13824
 			var stringLen uint64
13743 13825
 			for shift := uint(0); ; shift += 7 {
... ...
@@ -13762,13 +14864,13 @@ func (m *SecretReference_FileTarget) Unmarshal(dAtA []byte) error {
13762 13762
 			if postIndex > l {
13763 13763
 				return io.ErrUnexpectedEOF
13764 13764
 			}
13765
-			m.GID = string(dAtA[iNdEx:postIndex])
13765
+			m.ConfigID = string(dAtA[iNdEx:postIndex])
13766 13766
 			iNdEx = postIndex
13767
-		case 4:
13768
-			if wireType != 0 {
13769
-				return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType)
13767
+		case 2:
13768
+			if wireType != 2 {
13769
+				return fmt.Errorf("proto: wrong wireType = %d for field ConfigName", wireType)
13770 13770
 			}
13771
-			m.Mode = 0
13771
+			var stringLen uint64
13772 13772
 			for shift := uint(0); ; shift += 7 {
13773 13773
 				if shift >= 64 {
13774 13774
 					return ErrIntOverflowTypes
... ...
@@ -13778,11 +14880,53 @@ func (m *SecretReference_FileTarget) Unmarshal(dAtA []byte) error {
13778 13778
 				}
13779 13779
 				b := dAtA[iNdEx]
13780 13780
 				iNdEx++
13781
-				m.Mode |= (os.FileMode(b) & 0x7F) << shift
13781
+				stringLen |= (uint64(b) & 0x7F) << shift
13782 13782
 				if b < 0x80 {
13783 13783
 					break
13784 13784
 				}
13785 13785
 			}
13786
+			intStringLen := int(stringLen)
13787
+			if intStringLen < 0 {
13788
+				return ErrInvalidLengthTypes
13789
+			}
13790
+			postIndex := iNdEx + intStringLen
13791
+			if postIndex > l {
13792
+				return io.ErrUnexpectedEOF
13793
+			}
13794
+			m.ConfigName = string(dAtA[iNdEx:postIndex])
13795
+			iNdEx = postIndex
13796
+		case 3:
13797
+			if wireType != 2 {
13798
+				return fmt.Errorf("proto: wrong wireType = %d for field File", wireType)
13799
+			}
13800
+			var msglen int
13801
+			for shift := uint(0); ; shift += 7 {
13802
+				if shift >= 64 {
13803
+					return ErrIntOverflowTypes
13804
+				}
13805
+				if iNdEx >= l {
13806
+					return io.ErrUnexpectedEOF
13807
+				}
13808
+				b := dAtA[iNdEx]
13809
+				iNdEx++
13810
+				msglen |= (int(b) & 0x7F) << shift
13811
+				if b < 0x80 {
13812
+					break
13813
+				}
13814
+			}
13815
+			if msglen < 0 {
13816
+				return ErrInvalidLengthTypes
13817
+			}
13818
+			postIndex := iNdEx + msglen
13819
+			if postIndex > l {
13820
+				return io.ErrUnexpectedEOF
13821
+			}
13822
+			v := &FileTarget{}
13823
+			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
13824
+				return err
13825
+			}
13826
+			m.Target = &ConfigReference_File{v}
13827
+			iNdEx = postIndex
13786 13828
 		default:
13787 13829
 			iNdEx = preIndex
13788 13830
 			skippy, err := skipTypes(dAtA[iNdEx:])
... ...
@@ -14358,6 +15502,416 @@ func (m *RootRotation) Unmarshal(dAtA []byte) error {
14358 14358
 	}
14359 14359
 	return nil
14360 14360
 }
14361
+func (m *Privileges) Unmarshal(dAtA []byte) error {
14362
+	l := len(dAtA)
14363
+	iNdEx := 0
14364
+	for iNdEx < l {
14365
+		preIndex := iNdEx
14366
+		var wire uint64
14367
+		for shift := uint(0); ; shift += 7 {
14368
+			if shift >= 64 {
14369
+				return ErrIntOverflowTypes
14370
+			}
14371
+			if iNdEx >= l {
14372
+				return io.ErrUnexpectedEOF
14373
+			}
14374
+			b := dAtA[iNdEx]
14375
+			iNdEx++
14376
+			wire |= (uint64(b) & 0x7F) << shift
14377
+			if b < 0x80 {
14378
+				break
14379
+			}
14380
+		}
14381
+		fieldNum := int32(wire >> 3)
14382
+		wireType := int(wire & 0x7)
14383
+		if wireType == 4 {
14384
+			return fmt.Errorf("proto: Privileges: wiretype end group for non-group")
14385
+		}
14386
+		if fieldNum <= 0 {
14387
+			return fmt.Errorf("proto: Privileges: illegal tag %d (wire type %d)", fieldNum, wire)
14388
+		}
14389
+		switch fieldNum {
14390
+		case 1:
14391
+			if wireType != 2 {
14392
+				return fmt.Errorf("proto: wrong wireType = %d for field CredentialSpec", wireType)
14393
+			}
14394
+			var msglen int
14395
+			for shift := uint(0); ; shift += 7 {
14396
+				if shift >= 64 {
14397
+					return ErrIntOverflowTypes
14398
+				}
14399
+				if iNdEx >= l {
14400
+					return io.ErrUnexpectedEOF
14401
+				}
14402
+				b := dAtA[iNdEx]
14403
+				iNdEx++
14404
+				msglen |= (int(b) & 0x7F) << shift
14405
+				if b < 0x80 {
14406
+					break
14407
+				}
14408
+			}
14409
+			if msglen < 0 {
14410
+				return ErrInvalidLengthTypes
14411
+			}
14412
+			postIndex := iNdEx + msglen
14413
+			if postIndex > l {
14414
+				return io.ErrUnexpectedEOF
14415
+			}
14416
+			if m.CredentialSpec == nil {
14417
+				m.CredentialSpec = &Privileges_CredentialSpec{}
14418
+			}
14419
+			if err := m.CredentialSpec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
14420
+				return err
14421
+			}
14422
+			iNdEx = postIndex
14423
+		case 2:
14424
+			if wireType != 2 {
14425
+				return fmt.Errorf("proto: wrong wireType = %d for field SELinuxContext", wireType)
14426
+			}
14427
+			var msglen int
14428
+			for shift := uint(0); ; shift += 7 {
14429
+				if shift >= 64 {
14430
+					return ErrIntOverflowTypes
14431
+				}
14432
+				if iNdEx >= l {
14433
+					return io.ErrUnexpectedEOF
14434
+				}
14435
+				b := dAtA[iNdEx]
14436
+				iNdEx++
14437
+				msglen |= (int(b) & 0x7F) << shift
14438
+				if b < 0x80 {
14439
+					break
14440
+				}
14441
+			}
14442
+			if msglen < 0 {
14443
+				return ErrInvalidLengthTypes
14444
+			}
14445
+			postIndex := iNdEx + msglen
14446
+			if postIndex > l {
14447
+				return io.ErrUnexpectedEOF
14448
+			}
14449
+			if m.SELinuxContext == nil {
14450
+				m.SELinuxContext = &Privileges_SELinuxContext{}
14451
+			}
14452
+			if err := m.SELinuxContext.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
14453
+				return err
14454
+			}
14455
+			iNdEx = postIndex
14456
+		default:
14457
+			iNdEx = preIndex
14458
+			skippy, err := skipTypes(dAtA[iNdEx:])
14459
+			if err != nil {
14460
+				return err
14461
+			}
14462
+			if skippy < 0 {
14463
+				return ErrInvalidLengthTypes
14464
+			}
14465
+			if (iNdEx + skippy) > l {
14466
+				return io.ErrUnexpectedEOF
14467
+			}
14468
+			iNdEx += skippy
14469
+		}
14470
+	}
14471
+
14472
+	if iNdEx > l {
14473
+		return io.ErrUnexpectedEOF
14474
+	}
14475
+	return nil
14476
+}
14477
+func (m *Privileges_CredentialSpec) Unmarshal(dAtA []byte) error {
14478
+	l := len(dAtA)
14479
+	iNdEx := 0
14480
+	for iNdEx < l {
14481
+		preIndex := iNdEx
14482
+		var wire uint64
14483
+		for shift := uint(0); ; shift += 7 {
14484
+			if shift >= 64 {
14485
+				return ErrIntOverflowTypes
14486
+			}
14487
+			if iNdEx >= l {
14488
+				return io.ErrUnexpectedEOF
14489
+			}
14490
+			b := dAtA[iNdEx]
14491
+			iNdEx++
14492
+			wire |= (uint64(b) & 0x7F) << shift
14493
+			if b < 0x80 {
14494
+				break
14495
+			}
14496
+		}
14497
+		fieldNum := int32(wire >> 3)
14498
+		wireType := int(wire & 0x7)
14499
+		if wireType == 4 {
14500
+			return fmt.Errorf("proto: CredentialSpec: wiretype end group for non-group")
14501
+		}
14502
+		if fieldNum <= 0 {
14503
+			return fmt.Errorf("proto: CredentialSpec: illegal tag %d (wire type %d)", fieldNum, wire)
14504
+		}
14505
+		switch fieldNum {
14506
+		case 1:
14507
+			if wireType != 2 {
14508
+				return fmt.Errorf("proto: wrong wireType = %d for field File", wireType)
14509
+			}
14510
+			var stringLen uint64
14511
+			for shift := uint(0); ; shift += 7 {
14512
+				if shift >= 64 {
14513
+					return ErrIntOverflowTypes
14514
+				}
14515
+				if iNdEx >= l {
14516
+					return io.ErrUnexpectedEOF
14517
+				}
14518
+				b := dAtA[iNdEx]
14519
+				iNdEx++
14520
+				stringLen |= (uint64(b) & 0x7F) << shift
14521
+				if b < 0x80 {
14522
+					break
14523
+				}
14524
+			}
14525
+			intStringLen := int(stringLen)
14526
+			if intStringLen < 0 {
14527
+				return ErrInvalidLengthTypes
14528
+			}
14529
+			postIndex := iNdEx + intStringLen
14530
+			if postIndex > l {
14531
+				return io.ErrUnexpectedEOF
14532
+			}
14533
+			m.Source = &Privileges_CredentialSpec_File{string(dAtA[iNdEx:postIndex])}
14534
+			iNdEx = postIndex
14535
+		case 2:
14536
+			if wireType != 2 {
14537
+				return fmt.Errorf("proto: wrong wireType = %d for field Registry", wireType)
14538
+			}
14539
+			var stringLen uint64
14540
+			for shift := uint(0); ; shift += 7 {
14541
+				if shift >= 64 {
14542
+					return ErrIntOverflowTypes
14543
+				}
14544
+				if iNdEx >= l {
14545
+					return io.ErrUnexpectedEOF
14546
+				}
14547
+				b := dAtA[iNdEx]
14548
+				iNdEx++
14549
+				stringLen |= (uint64(b) & 0x7F) << shift
14550
+				if b < 0x80 {
14551
+					break
14552
+				}
14553
+			}
14554
+			intStringLen := int(stringLen)
14555
+			if intStringLen < 0 {
14556
+				return ErrInvalidLengthTypes
14557
+			}
14558
+			postIndex := iNdEx + intStringLen
14559
+			if postIndex > l {
14560
+				return io.ErrUnexpectedEOF
14561
+			}
14562
+			m.Source = &Privileges_CredentialSpec_Registry{string(dAtA[iNdEx:postIndex])}
14563
+			iNdEx = postIndex
14564
+		default:
14565
+			iNdEx = preIndex
14566
+			skippy, err := skipTypes(dAtA[iNdEx:])
14567
+			if err != nil {
14568
+				return err
14569
+			}
14570
+			if skippy < 0 {
14571
+				return ErrInvalidLengthTypes
14572
+			}
14573
+			if (iNdEx + skippy) > l {
14574
+				return io.ErrUnexpectedEOF
14575
+			}
14576
+			iNdEx += skippy
14577
+		}
14578
+	}
14579
+
14580
+	if iNdEx > l {
14581
+		return io.ErrUnexpectedEOF
14582
+	}
14583
+	return nil
14584
+}
14585
+func (m *Privileges_SELinuxContext) Unmarshal(dAtA []byte) error {
14586
+	l := len(dAtA)
14587
+	iNdEx := 0
14588
+	for iNdEx < l {
14589
+		preIndex := iNdEx
14590
+		var wire uint64
14591
+		for shift := uint(0); ; shift += 7 {
14592
+			if shift >= 64 {
14593
+				return ErrIntOverflowTypes
14594
+			}
14595
+			if iNdEx >= l {
14596
+				return io.ErrUnexpectedEOF
14597
+			}
14598
+			b := dAtA[iNdEx]
14599
+			iNdEx++
14600
+			wire |= (uint64(b) & 0x7F) << shift
14601
+			if b < 0x80 {
14602
+				break
14603
+			}
14604
+		}
14605
+		fieldNum := int32(wire >> 3)
14606
+		wireType := int(wire & 0x7)
14607
+		if wireType == 4 {
14608
+			return fmt.Errorf("proto: SELinuxContext: wiretype end group for non-group")
14609
+		}
14610
+		if fieldNum <= 0 {
14611
+			return fmt.Errorf("proto: SELinuxContext: illegal tag %d (wire type %d)", fieldNum, wire)
14612
+		}
14613
+		switch fieldNum {
14614
+		case 1:
14615
+			if wireType != 0 {
14616
+				return fmt.Errorf("proto: wrong wireType = %d for field Disable", wireType)
14617
+			}
14618
+			var v int
14619
+			for shift := uint(0); ; shift += 7 {
14620
+				if shift >= 64 {
14621
+					return ErrIntOverflowTypes
14622
+				}
14623
+				if iNdEx >= l {
14624
+					return io.ErrUnexpectedEOF
14625
+				}
14626
+				b := dAtA[iNdEx]
14627
+				iNdEx++
14628
+				v |= (int(b) & 0x7F) << shift
14629
+				if b < 0x80 {
14630
+					break
14631
+				}
14632
+			}
14633
+			m.Disable = bool(v != 0)
14634
+		case 2:
14635
+			if wireType != 2 {
14636
+				return fmt.Errorf("proto: wrong wireType = %d for field User", wireType)
14637
+			}
14638
+			var stringLen uint64
14639
+			for shift := uint(0); ; shift += 7 {
14640
+				if shift >= 64 {
14641
+					return ErrIntOverflowTypes
14642
+				}
14643
+				if iNdEx >= l {
14644
+					return io.ErrUnexpectedEOF
14645
+				}
14646
+				b := dAtA[iNdEx]
14647
+				iNdEx++
14648
+				stringLen |= (uint64(b) & 0x7F) << shift
14649
+				if b < 0x80 {
14650
+					break
14651
+				}
14652
+			}
14653
+			intStringLen := int(stringLen)
14654
+			if intStringLen < 0 {
14655
+				return ErrInvalidLengthTypes
14656
+			}
14657
+			postIndex := iNdEx + intStringLen
14658
+			if postIndex > l {
14659
+				return io.ErrUnexpectedEOF
14660
+			}
14661
+			m.User = string(dAtA[iNdEx:postIndex])
14662
+			iNdEx = postIndex
14663
+		case 3:
14664
+			if wireType != 2 {
14665
+				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
14666
+			}
14667
+			var stringLen uint64
14668
+			for shift := uint(0); ; shift += 7 {
14669
+				if shift >= 64 {
14670
+					return ErrIntOverflowTypes
14671
+				}
14672
+				if iNdEx >= l {
14673
+					return io.ErrUnexpectedEOF
14674
+				}
14675
+				b := dAtA[iNdEx]
14676
+				iNdEx++
14677
+				stringLen |= (uint64(b) & 0x7F) << shift
14678
+				if b < 0x80 {
14679
+					break
14680
+				}
14681
+			}
14682
+			intStringLen := int(stringLen)
14683
+			if intStringLen < 0 {
14684
+				return ErrInvalidLengthTypes
14685
+			}
14686
+			postIndex := iNdEx + intStringLen
14687
+			if postIndex > l {
14688
+				return io.ErrUnexpectedEOF
14689
+			}
14690
+			m.Role = string(dAtA[iNdEx:postIndex])
14691
+			iNdEx = postIndex
14692
+		case 4:
14693
+			if wireType != 2 {
14694
+				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
14695
+			}
14696
+			var stringLen uint64
14697
+			for shift := uint(0); ; shift += 7 {
14698
+				if shift >= 64 {
14699
+					return ErrIntOverflowTypes
14700
+				}
14701
+				if iNdEx >= l {
14702
+					return io.ErrUnexpectedEOF
14703
+				}
14704
+				b := dAtA[iNdEx]
14705
+				iNdEx++
14706
+				stringLen |= (uint64(b) & 0x7F) << shift
14707
+				if b < 0x80 {
14708
+					break
14709
+				}
14710
+			}
14711
+			intStringLen := int(stringLen)
14712
+			if intStringLen < 0 {
14713
+				return ErrInvalidLengthTypes
14714
+			}
14715
+			postIndex := iNdEx + intStringLen
14716
+			if postIndex > l {
14717
+				return io.ErrUnexpectedEOF
14718
+			}
14719
+			m.Type = string(dAtA[iNdEx:postIndex])
14720
+			iNdEx = postIndex
14721
+		case 5:
14722
+			if wireType != 2 {
14723
+				return fmt.Errorf("proto: wrong wireType = %d for field Level", wireType)
14724
+			}
14725
+			var stringLen uint64
14726
+			for shift := uint(0); ; shift += 7 {
14727
+				if shift >= 64 {
14728
+					return ErrIntOverflowTypes
14729
+				}
14730
+				if iNdEx >= l {
14731
+					return io.ErrUnexpectedEOF
14732
+				}
14733
+				b := dAtA[iNdEx]
14734
+				iNdEx++
14735
+				stringLen |= (uint64(b) & 0x7F) << shift
14736
+				if b < 0x80 {
14737
+					break
14738
+				}
14739
+			}
14740
+			intStringLen := int(stringLen)
14741
+			if intStringLen < 0 {
14742
+				return ErrInvalidLengthTypes
14743
+			}
14744
+			postIndex := iNdEx + intStringLen
14745
+			if postIndex > l {
14746
+				return io.ErrUnexpectedEOF
14747
+			}
14748
+			m.Level = string(dAtA[iNdEx:postIndex])
14749
+			iNdEx = postIndex
14750
+		default:
14751
+			iNdEx = preIndex
14752
+			skippy, err := skipTypes(dAtA[iNdEx:])
14753
+			if err != nil {
14754
+				return err
14755
+			}
14756
+			if skippy < 0 {
14757
+				return ErrInvalidLengthTypes
14758
+			}
14759
+			if (iNdEx + skippy) > l {
14760
+				return io.ErrUnexpectedEOF
14761
+			}
14762
+			iNdEx += skippy
14763
+		}
14764
+	}
14765
+
14766
+	if iNdEx > l {
14767
+		return io.ErrUnexpectedEOF
14768
+	}
14769
+	return nil
14770
+}
14361 14771
 func skipTypes(dAtA []byte) (n int, err error) {
14362 14772
 	l := len(dAtA)
14363 14773
 	iNdEx := 0
... ...
@@ -14466,276 +16020,296 @@ var (
14466 14466
 func init() { proto.RegisterFile("types.proto", fileDescriptorTypes) }
14467 14467
 
14468 14468
 var fileDescriptorTypes = []byte{
14469
-	// 4333 bytes of a gzipped FileDescriptorProto
14470
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x5a, 0x4f, 0x6c, 0x24, 0xc7,
14471
-	0x5a, 0xf7, 0xfc, 0xf5, 0xcc, 0x37, 0x63, 0xbb, 0xb7, 0xd6, 0xd9, 0x78, 0x27, 0x1b, 0x7b, 0xd2,
14472
-	0xc9, 0xbe, 0xfc, 0x79, 0xd1, 0x64, 0xd7, 0xfb, 0x12, 0x6d, 0x12, 0x5e, 0x92, 0xf9, 0xe7, 0xf5,
14473
-	0xbc, 0xb5, 0x67, 0x46, 0x35, 0xe3, 0xdd, 0x97, 0x03, 0xb4, 0xca, 0xdd, 0xe5, 0x71, 0xc7, 0x3d,
14474
-	0x5d, 0x43, 0x77, 0x8f, 0xbd, 0x03, 0x42, 0xac, 0x38, 0x00, 0xf2, 0x89, 0x23, 0x12, 0xf2, 0x09,
14475
-	0x4e, 0x1c, 0xb8, 0x70, 0x40, 0x70, 0x21, 0x48, 0x1c, 0x72, 0xe3, 0x01, 0x12, 0x7a, 0x02, 0xc9,
14476
-	0x10, 0x23, 0x71, 0x43, 0x70, 0x79, 0xe2, 0x02, 0x12, 0xaa, 0x3f, 0xdd, 0xd3, 0xf6, 0x8e, 0xed,
14477
-	0x0d, 0xe1, 0x62, 0x77, 0x7d, 0xf5, 0xfb, 0xbe, 0xaa, 0xfa, 0xea, 0xab, 0xaa, 0xdf, 0x57, 0x35,
14478
-	0x50, 0x08, 0x26, 0x23, 0xea, 0x57, 0x46, 0x1e, 0x0b, 0x18, 0x42, 0x16, 0x33, 0x0f, 0xa8, 0x57,
14479
-	0xf1, 0x8f, 0x88, 0x37, 0x3c, 0xb0, 0x83, 0xca, 0xe1, 0xfd, 0xd2, 0xda, 0x80, 0xb1, 0x81, 0x43,
14480
-	0x3f, 0x10, 0x88, 0xdd, 0xf1, 0xde, 0x07, 0x81, 0x3d, 0xa4, 0x7e, 0x40, 0x86, 0x23, 0xa9, 0x54,
14481
-	0x5a, 0xbd, 0x08, 0xb0, 0xc6, 0x1e, 0x09, 0x6c, 0xe6, 0xaa, 0xfa, 0xe5, 0x01, 0x1b, 0x30, 0xf1,
14482
-	0xf9, 0x01, 0xff, 0x92, 0x52, 0x7d, 0x0d, 0xe6, 0x9f, 0x50, 0xcf, 0xb7, 0x99, 0x8b, 0x96, 0x21,
14483
-	0x63, 0xbb, 0x16, 0x7d, 0xb6, 0x92, 0x28, 0x27, 0xde, 0x49, 0x63, 0x59, 0xd0, 0xef, 0x01, 0xb4,
14484
-	0xf8, 0x47, 0xd3, 0x0d, 0xbc, 0x09, 0xd2, 0x20, 0x75, 0x40, 0x27, 0x02, 0x91, 0xc7, 0xfc, 0x93,
14485
-	0x4b, 0x0e, 0x89, 0xb3, 0x92, 0x94, 0x92, 0x43, 0xe2, 0xe8, 0xdf, 0x26, 0xa0, 0x50, 0x75, 0x5d,
14486
-	0x16, 0x88, 0xd6, 0x7d, 0x84, 0x20, 0xed, 0x92, 0x21, 0x55, 0x4a, 0xe2, 0x1b, 0xd5, 0x21, 0xeb,
14487
-	0x90, 0x5d, 0xea, 0xf8, 0x2b, 0xc9, 0x72, 0xea, 0x9d, 0xc2, 0xfa, 0x0f, 0x2b, 0x2f, 0x0e, 0xb9,
14488
-	0x12, 0x33, 0x52, 0xd9, 0x12, 0x68, 0xd1, 0x09, 0xac, 0x54, 0xd1, 0x67, 0x30, 0x6f, 0xbb, 0x96,
14489
-	0x6d, 0x52, 0x7f, 0x25, 0x2d, 0xac, 0xac, 0xce, 0xb2, 0x32, 0xed, 0x7d, 0x2d, 0xfd, 0xcd, 0xe9,
14490
-	0xda, 0x1c, 0x0e, 0x95, 0x4a, 0x1f, 0x43, 0x21, 0x66, 0x76, 0xc6, 0xd8, 0x96, 0x21, 0x73, 0x48,
14491
-	0x9c, 0x31, 0x55, 0xa3, 0x93, 0x85, 0x4f, 0x92, 0x0f, 0x13, 0xfa, 0x97, 0x90, 0xc7, 0xd4, 0x67,
14492
-	0x63, 0xcf, 0xa4, 0x3e, 0x7a, 0x17, 0xf2, 0x2e, 0x71, 0x99, 0x61, 0x8e, 0xc6, 0xbe, 0x50, 0x4f,
14493
-	0xd5, 0x8a, 0x67, 0xa7, 0x6b, 0xb9, 0x36, 0x71, 0x59, 0xbd, 0xbb, 0xe3, 0xe3, 0x1c, 0xaf, 0xae,
14494
-	0x8f, 0xc6, 0x3e, 0x7a, 0x03, 0x8a, 0x43, 0x3a, 0x64, 0xde, 0xc4, 0xd8, 0x9d, 0x04, 0xd4, 0x17,
14495
-	0x86, 0x53, 0xb8, 0x20, 0x65, 0x35, 0x2e, 0xd2, 0x7f, 0x2f, 0x01, 0xcb, 0xa1, 0x6d, 0x4c, 0x7f,
14496
-	0x75, 0x6c, 0x7b, 0x74, 0x48, 0xdd, 0xc0, 0x47, 0x1f, 0x42, 0xd6, 0xb1, 0x87, 0x76, 0x20, 0xdb,
14497
-	0x28, 0xac, 0xbf, 0x3e, 0x6b, 0xb4, 0x51, 0xaf, 0xb0, 0x02, 0xa3, 0x2a, 0x14, 0x3d, 0xea, 0x53,
14498
-	0xef, 0x50, 0x7a, 0x52, 0x34, 0x79, 0xad, 0xf2, 0x39, 0x15, 0x7d, 0x03, 0x72, 0x5d, 0x87, 0x04,
14499
-	0x7b, 0xcc, 0x1b, 0x22, 0x1d, 0x8a, 0xc4, 0x33, 0xf7, 0xed, 0x80, 0x9a, 0xc1, 0xd8, 0x0b, 0x67,
14500
-	0xf5, 0x9c, 0x0c, 0xdd, 0x82, 0x24, 0x93, 0x0d, 0xe5, 0x6b, 0xd9, 0xb3, 0xd3, 0xb5, 0x64, 0xa7,
14501
-	0x87, 0x93, 0xcc, 0xd7, 0x3f, 0x85, 0x1b, 0x5d, 0x67, 0x3c, 0xb0, 0xdd, 0x06, 0xf5, 0x4d, 0xcf,
14502
-	0x1e, 0x71, 0xeb, 0x3c, 0x3c, 0x78, 0xec, 0x87, 0xe1, 0xc1, 0xbf, 0xa3, 0x90, 0x49, 0x4e, 0x43,
14503
-	0x46, 0xff, 0x9d, 0x24, 0xdc, 0x68, 0xba, 0x03, 0xdb, 0xa5, 0x71, 0xed, 0xbb, 0xb0, 0x48, 0x85,
14504
-	0xd0, 0x38, 0x94, 0x61, 0xac, 0xec, 0x2c, 0x48, 0x69, 0x18, 0xdb, 0xad, 0x0b, 0xf1, 0x76, 0x7f,
14505
-	0xd6, 0xf0, 0x5f, 0xb0, 0x3e, 0x33, 0xea, 0x9a, 0x30, 0x3f, 0x12, 0x83, 0xf0, 0x57, 0x52, 0xc2,
14506
-	0xd6, 0xdd, 0x59, 0xb6, 0x5e, 0x18, 0x67, 0x18, 0x7c, 0x4a, 0xf7, 0xfb, 0x04, 0xdf, 0xbf, 0x26,
14507
-	0x60, 0xa9, 0xcd, 0xac, 0x73, 0x7e, 0x28, 0x41, 0x6e, 0x9f, 0xf9, 0x41, 0x6c, 0xa1, 0x45, 0x65,
14508
-	0xf4, 0x10, 0x72, 0x23, 0x35, 0x7d, 0x6a, 0xf6, 0xef, 0xcc, 0xee, 0xb2, 0xc4, 0xe0, 0x08, 0x8d,
14509
-	0x3e, 0x85, 0xbc, 0x17, 0xc6, 0xc4, 0x4a, 0xea, 0x65, 0x02, 0x67, 0x8a, 0x47, 0x3f, 0x86, 0xac,
14510
-	0x9c, 0x84, 0x95, 0xb4, 0xd0, 0xbc, 0xfb, 0x52, 0x3e, 0xc7, 0x4a, 0x49, 0xff, 0x79, 0x02, 0x34,
14511
-	0x4c, 0xf6, 0x82, 0x6d, 0x3a, 0xdc, 0xa5, 0x5e, 0x2f, 0x20, 0xc1, 0xd8, 0x47, 0xb7, 0x20, 0xeb,
14512
-	0x50, 0x62, 0x51, 0x4f, 0x0c, 0x32, 0x87, 0x55, 0x09, 0xed, 0xf0, 0x20, 0x27, 0xe6, 0x3e, 0xd9,
14513
-	0xb5, 0x1d, 0x3b, 0x98, 0x88, 0x61, 0x2e, 0xce, 0x9e, 0xe5, 0x8b, 0x36, 0x2b, 0x38, 0xa6, 0x88,
14514
-	0xcf, 0x99, 0x41, 0x2b, 0x30, 0x3f, 0xa4, 0xbe, 0x4f, 0x06, 0x54, 0x8c, 0x3e, 0x8f, 0xc3, 0xa2,
14515
-	0xfe, 0x29, 0x14, 0xe3, 0x7a, 0xa8, 0x00, 0xf3, 0x3b, 0xed, 0xc7, 0xed, 0xce, 0xd3, 0xb6, 0x36,
14516
-	0x87, 0x96, 0xa0, 0xb0, 0xd3, 0xc6, 0xcd, 0x6a, 0x7d, 0xb3, 0x5a, 0xdb, 0x6a, 0x6a, 0x09, 0xb4,
14517
-	0x00, 0xf9, 0x69, 0x31, 0xa9, 0xff, 0x69, 0x02, 0x80, 0x4f, 0xa0, 0x1a, 0xd4, 0x27, 0x90, 0xf1,
14518
-	0x03, 0x12, 0xc8, 0x89, 0x5b, 0x5c, 0x7f, 0x6b, 0x56, 0xaf, 0xa7, 0xf0, 0x0a, 0xff, 0x47, 0xb1,
14519
-	0x54, 0x89, 0xf7, 0x30, 0x79, 0xae, 0x87, 0x7c, 0x0d, 0x11, 0xcb, 0xf2, 0x54, 0xc7, 0xc5, 0xb7,
14520
-	0xfe, 0x29, 0x64, 0x84, 0xf6, 0xf9, 0xee, 0xe6, 0x20, 0xdd, 0xe0, 0x5f, 0x09, 0x94, 0x87, 0x0c,
14521
-	0x6e, 0x56, 0x1b, 0x5f, 0x6a, 0x49, 0xa4, 0x41, 0xb1, 0xd1, 0xea, 0xd5, 0x3b, 0xed, 0x76, 0xb3,
14522
-	0xde, 0x6f, 0x36, 0xb4, 0x94, 0x7e, 0x17, 0x32, 0xad, 0x21, 0xb7, 0x7c, 0x87, 0x47, 0xc5, 0x1e,
14523
-	0xf5, 0xa8, 0x6b, 0x86, 0xc1, 0x36, 0x15, 0xe8, 0x3f, 0xcb, 0x43, 0x66, 0x9b, 0x8d, 0xdd, 0x00,
14524
-	0xad, 0xc7, 0x56, 0xf6, 0xe2, 0xec, 0xcd, 0x59, 0x00, 0x2b, 0xfd, 0xc9, 0x88, 0xaa, 0x95, 0x7f,
14525
-	0x0b, 0xb2, 0x32, 0x7e, 0xd4, 0x70, 0x54, 0x89, 0xcb, 0x03, 0xe2, 0x0d, 0x68, 0xa0, 0xc6, 0xa3,
14526
-	0x4a, 0xe8, 0x1d, 0xc8, 0x79, 0x94, 0x58, 0xcc, 0x75, 0x26, 0x22, 0xcc, 0x72, 0x72, 0xeb, 0xc5,
14527
-	0x94, 0x58, 0x1d, 0xd7, 0x99, 0xe0, 0xa8, 0x16, 0x6d, 0x42, 0x71, 0xd7, 0x76, 0x2d, 0x83, 0x8d,
14528
-	0xe4, 0x3e, 0x98, 0xb9, 0x3c, 0x28, 0x65, 0xaf, 0x6a, 0xb6, 0x6b, 0x75, 0x24, 0x18, 0x17, 0x76,
14529
-	0xa7, 0x05, 0xd4, 0x86, 0xc5, 0x43, 0xe6, 0x8c, 0x87, 0x34, 0xb2, 0x95, 0x15, 0xb6, 0xde, 0xbe,
14530
-	0xdc, 0xd6, 0x13, 0x81, 0x0f, 0xad, 0x2d, 0x1c, 0xc6, 0x8b, 0xe8, 0x31, 0x2c, 0x04, 0xc3, 0xd1,
14531
-	0x9e, 0x1f, 0x99, 0x9b, 0x17, 0xe6, 0x7e, 0x70, 0x85, 0xc3, 0x38, 0x3c, 0xb4, 0x56, 0x0c, 0x62,
14532
-	0xa5, 0xd2, 0x6f, 0xa5, 0xa0, 0x10, 0xeb, 0x39, 0xea, 0x41, 0x61, 0xe4, 0xb1, 0x11, 0x19, 0x88,
14533
-	0xbd, 0x5c, 0xcd, 0xc5, 0xfd, 0x97, 0x1a, 0x75, 0xa5, 0x3b, 0x55, 0xc4, 0x71, 0x2b, 0xfa, 0x49,
14534
-	0x12, 0x0a, 0xb1, 0x4a, 0xf4, 0x1e, 0xe4, 0x70, 0x17, 0xb7, 0x9e, 0x54, 0xfb, 0x4d, 0x6d, 0xae,
14535
-	0x74, 0xe7, 0xf8, 0xa4, 0xbc, 0x22, 0xac, 0xc5, 0x0d, 0x74, 0x3d, 0xfb, 0x90, 0x87, 0xde, 0x3b,
14536
-	0x30, 0x1f, 0x42, 0x13, 0xa5, 0xd7, 0x8e, 0x4f, 0xca, 0xaf, 0x5e, 0x84, 0xc6, 0x90, 0xb8, 0xb7,
14537
-	0x59, 0xc5, 0xcd, 0x86, 0x96, 0x9c, 0x8d, 0xc4, 0xbd, 0x7d, 0xe2, 0x51, 0x0b, 0xfd, 0x00, 0xb2,
14538
-	0x0a, 0x98, 0x2a, 0x95, 0x8e, 0x4f, 0xca, 0xb7, 0x2e, 0x02, 0xa7, 0x38, 0xdc, 0xdb, 0xaa, 0x3e,
14539
-	0x69, 0x6a, 0xe9, 0xd9, 0x38, 0xdc, 0x73, 0xc8, 0x21, 0x45, 0x6f, 0x41, 0x46, 0xc2, 0x32, 0xa5,
14540
-	0xdb, 0xc7, 0x27, 0xe5, 0x57, 0x5e, 0x30, 0xc7, 0x51, 0xa5, 0x95, 0xdf, 0xfd, 0xc3, 0xd5, 0xb9,
14541
-	0xbf, 0xf8, 0xa3, 0x55, 0xed, 0x62, 0x75, 0xe9, 0xbf, 0x13, 0xb0, 0x70, 0x6e, 0xca, 0x91, 0x0e,
14542
-	0x59, 0x97, 0x99, 0x6c, 0x24, 0xb7, 0xf8, 0x5c, 0x0d, 0xce, 0x4e, 0xd7, 0xb2, 0x6d, 0x56, 0x67,
14543
-	0xa3, 0x09, 0x56, 0x35, 0xe8, 0xf1, 0x85, 0x43, 0xea, 0xc1, 0x4b, 0xc6, 0xd3, 0xcc, 0x63, 0xea,
14544
-	0x73, 0x58, 0xb0, 0x3c, 0xfb, 0x90, 0x7a, 0x86, 0xc9, 0xdc, 0x3d, 0x7b, 0xa0, 0xb6, 0xef, 0xd2,
14545
-	0x2c, 0x9b, 0x0d, 0x01, 0xc4, 0x45, 0xa9, 0x50, 0x17, 0xf8, 0xef, 0x71, 0x40, 0x95, 0x9e, 0x40,
14546
-	0x31, 0x1e, 0xa1, 0xe8, 0x75, 0x00, 0xdf, 0xfe, 0x35, 0xaa, 0x38, 0x8f, 0x60, 0x48, 0x38, 0xcf,
14547
-	0x25, 0x82, 0xf1, 0xa0, 0xb7, 0x21, 0x3d, 0x64, 0x96, 0xb4, 0xb3, 0x50, 0xbb, 0xc9, 0xcf, 0xc9,
14548
-	0x7f, 0x3c, 0x5d, 0x2b, 0x30, 0xbf, 0xb2, 0x61, 0x3b, 0x74, 0x9b, 0x59, 0x14, 0x0b, 0x80, 0x7e,
14549
-	0x08, 0x69, 0xbe, 0x55, 0xa0, 0xd7, 0x20, 0x5d, 0x6b, 0xb5, 0x1b, 0xda, 0x5c, 0xe9, 0xc6, 0xf1,
14550
-	0x49, 0x79, 0x41, 0xb8, 0x84, 0x57, 0xf0, 0xd8, 0x45, 0x6b, 0x90, 0x7d, 0xd2, 0xd9, 0xda, 0xd9,
14551
-	0xe6, 0xe1, 0x75, 0xf3, 0xf8, 0xa4, 0xbc, 0x14, 0x55, 0x4b, 0xa7, 0xa1, 0xd7, 0x21, 0xd3, 0xdf,
14552
-	0xee, 0x6e, 0xf4, 0xb4, 0x64, 0x09, 0x1d, 0x9f, 0x94, 0x17, 0xa3, 0x7a, 0xd1, 0xe7, 0xd2, 0x0d,
14553
-	0x35, 0xab, 0xf9, 0x48, 0xae, 0xff, 0x22, 0x09, 0x0b, 0x98, 0x93, 0x6d, 0x2f, 0xe8, 0x32, 0xc7,
14554
-	0x36, 0x27, 0xa8, 0x0b, 0x79, 0x93, 0xb9, 0x96, 0x1d, 0x5b, 0x53, 0xeb, 0x97, 0x1c, 0x8c, 0x53,
14555
-	0xad, 0xb0, 0x54, 0x0f, 0x35, 0xf1, 0xd4, 0x08, 0xfa, 0x00, 0x32, 0x16, 0x75, 0xc8, 0x44, 0x9d,
14556
-	0xd0, 0xb7, 0x2b, 0x92, 0xce, 0x57, 0x42, 0x3a, 0x5f, 0x69, 0x28, 0x3a, 0x8f, 0x25, 0x4e, 0x50,
14557
-	0x49, 0xf2, 0xcc, 0x20, 0x41, 0x40, 0x87, 0xa3, 0x40, 0x1e, 0xcf, 0x69, 0x5c, 0x18, 0x92, 0x67,
14558
-	0x55, 0x25, 0x42, 0xf7, 0x21, 0x7b, 0x64, 0xbb, 0x16, 0x3b, 0x52, 0x27, 0xf0, 0x15, 0x46, 0x15,
14559
-	0x50, 0x3f, 0xe6, 0xa7, 0xee, 0x85, 0x6e, 0x72, 0x7f, 0xb7, 0x3b, 0xed, 0x66, 0xe8, 0x6f, 0x55,
14560
-	0xdf, 0x71, 0xdb, 0xcc, 0xe5, 0x6b, 0x05, 0x3a, 0x6d, 0x63, 0xa3, 0xda, 0xda, 0xda, 0xc1, 0xdc,
14561
-	0xe7, 0xcb, 0xc7, 0x27, 0x65, 0x2d, 0x82, 0x6c, 0x10, 0xdb, 0xe1, 0x94, 0xf0, 0x36, 0xa4, 0xaa,
14562
-	0xed, 0x2f, 0xb5, 0x64, 0x49, 0x3b, 0x3e, 0x29, 0x17, 0xa3, 0xea, 0xaa, 0x3b, 0x99, 0x2e, 0xa3,
14563
-	0x8b, 0xed, 0xea, 0x7f, 0x93, 0x82, 0xe2, 0xce, 0xc8, 0x22, 0x01, 0x95, 0x31, 0x89, 0xca, 0x50,
14564
-	0x18, 0x11, 0x8f, 0x38, 0x0e, 0x75, 0x6c, 0x7f, 0xa8, 0x12, 0x95, 0xb8, 0x08, 0x7d, 0xfc, 0xb2,
14565
-	0x6e, 0xac, 0xe5, 0x78, 0x9c, 0xfd, 0xfe, 0x3f, 0xaf, 0x25, 0x42, 0x87, 0xee, 0xc0, 0xe2, 0x9e,
14566
-	0xec, 0xad, 0x41, 0x4c, 0x31, 0xb1, 0x29, 0x31, 0xb1, 0x95, 0x59, 0x13, 0x1b, 0xef, 0x56, 0x45,
14567
-	0x0d, 0xb2, 0x2a, 0xb4, 0xf0, 0xc2, 0x5e, 0xbc, 0x88, 0x1e, 0xc0, 0xfc, 0x90, 0xb9, 0x76, 0xc0,
14568
-	0xbc, 0xeb, 0x67, 0x21, 0x44, 0xa2, 0xf7, 0xe0, 0x06, 0x9f, 0xdc, 0xb0, 0x3f, 0xa2, 0x5a, 0x9c,
14569
-	0x58, 0x49, 0xbc, 0x34, 0x24, 0xcf, 0x54, 0x83, 0x98, 0x8b, 0x51, 0x0d, 0x32, 0xcc, 0xe3, 0x94,
14570
-	0x28, 0x2b, 0xba, 0xfb, 0xfe, 0xb5, 0xdd, 0x95, 0x85, 0x0e, 0xd7, 0xc1, 0x52, 0x55, 0xff, 0x08,
14571
-	0x16, 0xce, 0x0d, 0x82, 0x33, 0x81, 0x6e, 0x75, 0xa7, 0xd7, 0xd4, 0xe6, 0x50, 0x11, 0x72, 0xf5,
14572
-	0x4e, 0xbb, 0xdf, 0x6a, 0xef, 0x70, 0x2a, 0x53, 0x84, 0x1c, 0xee, 0x6c, 0x6d, 0xd5, 0xaa, 0xf5,
14573
-	0xc7, 0x5a, 0x52, 0xaf, 0x40, 0x21, 0x66, 0x0d, 0x2d, 0x02, 0xf4, 0xfa, 0x9d, 0xae, 0xb1, 0xd1,
14574
-	0xc2, 0xbd, 0xbe, 0x24, 0x42, 0xbd, 0x7e, 0x15, 0xf7, 0x95, 0x20, 0xa1, 0xff, 0x47, 0x32, 0x9c,
14575
-	0x51, 0xc5, 0x7d, 0x6a, 0xe7, 0xb9, 0xcf, 0x15, 0x9d, 0x57, 0xec, 0x67, 0x5a, 0x88, 0x38, 0xd0,
14576
-	0xc7, 0x00, 0x22, 0x70, 0xa8, 0x65, 0x90, 0x40, 0x4d, 0x7c, 0xe9, 0x05, 0x27, 0xf7, 0xc3, 0x7c,
14577
-	0x19, 0xe7, 0x15, 0xba, 0x1a, 0xa0, 0x1f, 0x43, 0xd1, 0x64, 0xc3, 0x91, 0x43, 0x95, 0x72, 0xea,
14578
-	0x5a, 0xe5, 0x42, 0x84, 0xaf, 0x06, 0x71, 0xf6, 0x95, 0x3e, 0xcf, 0x0f, 0x7f, 0x3b, 0x11, 0x7a,
14579
-	0x66, 0x06, 0xe1, 0x2a, 0x42, 0x6e, 0xa7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x47, 0x5a, 0x02, 0x01,
14580
-	0x64, 0x85, 0xab, 0x1b, 0x5a, 0x92, 0x13, 0xc5, 0x7a, 0x67, 0xbb, 0xbb, 0xd5, 0x14, 0x94, 0x0b,
14581
-	0x2d, 0x83, 0x16, 0x3a, 0xdb, 0x10, 0x8e, 0x6c, 0x36, 0xb4, 0x34, 0xba, 0x09, 0x4b, 0x91, 0x54,
14582
-	0x69, 0x66, 0xd0, 0x2d, 0x40, 0x91, 0x70, 0x6a, 0x22, 0xab, 0xff, 0x06, 0x2c, 0xd5, 0x99, 0x1b,
14583
-	0x10, 0xdb, 0x8d, 0x48, 0xf4, 0x3a, 0x1f, 0xb4, 0x12, 0x19, 0xb6, 0x25, 0xf7, 0xf4, 0xda, 0xd2,
14584
-	0xd9, 0xe9, 0x5a, 0x21, 0x82, 0xb6, 0x1a, 0x7c, 0xa4, 0x61, 0xc1, 0xe2, 0xeb, 0x77, 0x64, 0x5b,
14585
-	0xc2, 0xb9, 0x99, 0xda, 0xfc, 0xd9, 0xe9, 0x5a, 0xaa, 0xdb, 0x6a, 0x60, 0x2e, 0x43, 0xaf, 0x41,
14586
-	0x9e, 0x3e, 0xb3, 0x03, 0xc3, 0xe4, 0x7b, 0x38, 0x77, 0x60, 0x06, 0xe7, 0xb8, 0xa0, 0xce, 0xb7,
14587
-	0xec, 0x1a, 0x40, 0x97, 0x79, 0x81, 0x6a, 0xf9, 0x47, 0x90, 0x19, 0x31, 0x4f, 0x64, 0xb0, 0x97,
14588
-	0xe6, 0xeb, 0x1c, 0x2e, 0x03, 0x15, 0x4b, 0xb0, 0xfe, 0x97, 0x49, 0x80, 0x3e, 0xf1, 0x0f, 0x94,
14589
-	0x91, 0x87, 0x90, 0x8f, 0xee, 0x3e, 0x54, 0x2a, 0x7c, 0xe5, 0x6c, 0x47, 0x60, 0xf4, 0x20, 0x0c,
14590
-	0x36, 0x99, 0x1e, 0xcc, 0x4c, 0x65, 0xc2, 0x86, 0x66, 0x31, 0xec, 0xf3, 0x39, 0x00, 0x3f, 0x12,
14591
-	0xa9, 0xe7, 0xa9, 0x99, 0xe7, 0x9f, 0xa8, 0x2e, 0x8e, 0x05, 0xe9, 0x34, 0x45, 0x30, 0xdf, 0x9c,
14592
-	0xd5, 0xc8, 0x85, 0x19, 0xd9, 0x9c, 0xc3, 0x53, 0x3d, 0xf4, 0x39, 0x14, 0xf8, 0xb8, 0x0d, 0x5f,
14593
-	0xd4, 0x29, 0x6e, 0x79, 0xa9, 0xab, 0xa4, 0x05, 0x0c, 0xa3, 0xe8, 0xbb, 0xa6, 0xc1, 0xa2, 0x37,
14594
-	0x76, 0xf9, 0xb0, 0x95, 0x0d, 0xdd, 0x86, 0x57, 0xdb, 0x34, 0x38, 0x62, 0xde, 0x41, 0x35, 0x08,
14595
-	0x88, 0xb9, 0x3f, 0xa4, 0xae, 0xf2, 0x71, 0x8c, 0x58, 0x27, 0xce, 0x11, 0xeb, 0x15, 0x98, 0x27,
14596
-	0x8e, 0x4d, 0x7c, 0x2a, 0xd9, 0x48, 0x1e, 0x87, 0x45, 0x4e, 0xff, 0x79, 0x32, 0x41, 0x7d, 0x9f,
14597
-	0xca, 0x14, 0x38, 0x8f, 0xa7, 0x02, 0xfd, 0xef, 0x93, 0x00, 0xad, 0x6e, 0x75, 0x5b, 0x99, 0x6f,
14598
-	0x40, 0x76, 0x8f, 0x0c, 0x6d, 0x67, 0x72, 0xd5, 0x02, 0x9f, 0xe2, 0x2b, 0x55, 0x69, 0x68, 0x43,
14599
-	0xe8, 0x60, 0xa5, 0x2b, 0xb2, 0x82, 0xf1, 0xae, 0x4b, 0x83, 0x28, 0x2b, 0x10, 0x25, 0x4e, 0x41,
14600
-	0x3c, 0xe2, 0x46, 0x33, 0x23, 0x0b, 0xbc, 0xeb, 0x03, 0x12, 0xd0, 0x23, 0x32, 0x09, 0x57, 0xa5,
14601
-	0x2a, 0xa2, 0x4d, 0x9e, 0x2d, 0xf8, 0xd4, 0x3b, 0xa4, 0xd6, 0x4a, 0x46, 0x84, 0xe0, 0x75, 0xfd,
14602
-	0xc1, 0x0a, 0x2e, 0xc9, 0x55, 0xa4, 0x5d, 0xfa, 0x54, 0x30, 0x82, 0x69, 0xd5, 0x77, 0x4a, 0xe0,
14603
-	0xef, 0xc1, 0xc2, 0xb9, 0x71, 0xbe, 0x90, 0x8e, 0xb5, 0xba, 0x4f, 0x7e, 0xa4, 0xa5, 0xd5, 0xd7,
14604
-	0x47, 0x5a, 0x56, 0xff, 0xe3, 0x94, 0x5c, 0x47, 0xca, 0xab, 0xb3, 0xaf, 0xd4, 0x72, 0x22, 0xfa,
14605
-	0x4d, 0xe6, 0xa8, 0xf8, 0x7e, 0xfb, 0xea, 0xe5, 0xc5, 0xe9, 0xbd, 0x80, 0xe3, 0x48, 0x11, 0xad,
14606
-	0x41, 0x41, 0xce, 0xbf, 0xc1, 0xe3, 0x49, 0xb8, 0x75, 0x01, 0x83, 0x14, 0x71, 0x4d, 0x74, 0x17,
14607
-	0x16, 0x47, 0xe3, 0x5d, 0xc7, 0xf6, 0xf7, 0xa9, 0x25, 0x31, 0x69, 0x81, 0x59, 0x88, 0xa4, 0x02,
14608
-	0xb6, 0x0d, 0x45, 0x25, 0x30, 0x04, 0xb5, 0xcb, 0x88, 0x0e, 0xbd, 0x77, 0x5d, 0x87, 0xa4, 0x8a,
14609
-	0x60, 0x7c, 0x85, 0xd1, 0xb4, 0xa0, 0x37, 0x20, 0x17, 0x76, 0x16, 0xad, 0x40, 0xaa, 0x5f, 0xef,
14610
-	0x6a, 0x73, 0xa5, 0xa5, 0xe3, 0x93, 0x72, 0x21, 0x14, 0xf7, 0xeb, 0x5d, 0x5e, 0xb3, 0xd3, 0xe8,
14611
-	0x6a, 0x89, 0xf3, 0x35, 0x3b, 0x8d, 0x6e, 0x29, 0xcd, 0x29, 0x86, 0xbe, 0x07, 0x85, 0x58, 0x0b,
14612
-	0xe8, 0x4d, 0x98, 0x6f, 0xb5, 0x1f, 0xe1, 0x66, 0xaf, 0xa7, 0xcd, 0x95, 0x6e, 0x1d, 0x9f, 0x94,
14613
-	0x51, 0xac, 0xb6, 0xe5, 0x0e, 0xf8, 0xfc, 0xa0, 0xd7, 0x21, 0xbd, 0xd9, 0xe1, 0x47, 0x97, 0xe4,
14614
-	0x92, 0x31, 0xc4, 0x26, 0xf3, 0x83, 0xd2, 0x4d, 0xc5, 0x5d, 0xe2, 0x86, 0xf5, 0x3f, 0x48, 0x40,
14615
-	0x56, 0x52, 0xea, 0x99, 0x13, 0x55, 0x85, 0xf9, 0x30, 0xd1, 0x93, 0x3c, 0xff, 0xed, 0xcb, 0x39,
14616
-	0x79, 0x45, 0x51, 0x68, 0x19, 0x7e, 0xa1, 0x5e, 0xe9, 0x13, 0x28, 0xc6, 0x2b, 0xbe, 0x53, 0xf0,
14617
-	0xfd, 0x3a, 0x14, 0x78, 0x7c, 0x87, 0xdc, 0x7c, 0x1d, 0xb2, 0x92, 0xf6, 0x47, 0x5b, 0xe9, 0xe5,
14618
-	0x09, 0x82, 0x42, 0xa2, 0x87, 0x30, 0x2f, 0x93, 0x8a, 0xf0, 0x0a, 0x6c, 0xf5, 0xea, 0x55, 0x84,
14619
-	0x43, 0xb8, 0xfe, 0x39, 0xa4, 0xbb, 0x94, 0x7a, 0xdc, 0xf7, 0x2e, 0xb3, 0xe8, 0xf4, 0xf4, 0x51,
14620
-	0xf9, 0x90, 0x45, 0x5b, 0x0d, 0x9e, 0x0f, 0x59, 0xb4, 0x65, 0x45, 0x37, 0x18, 0xc9, 0xd8, 0x0d,
14621
-	0x46, 0x1f, 0x8a, 0x4f, 0xa9, 0x3d, 0xd8, 0x0f, 0xa8, 0x25, 0x0c, 0xbd, 0x0f, 0xe9, 0x11, 0x8d,
14622
-	0x3a, 0xbf, 0x32, 0x33, 0xc0, 0x28, 0xf5, 0xb0, 0x40, 0xf1, 0x7d, 0xe4, 0x48, 0x68, 0xab, 0x8b,
14623
-	0x57, 0x55, 0xd2, 0xff, 0x2e, 0x09, 0x8b, 0x2d, 0xdf, 0x1f, 0x13, 0xd7, 0x0c, 0x89, 0xc9, 0x67,
14624
-	0xe7, 0x89, 0xc9, 0x3b, 0x33, 0x47, 0x78, 0x4e, 0xe5, 0xfc, 0xc5, 0x8c, 0x3a, 0x1c, 0x92, 0xd1,
14625
-	0xe1, 0xa0, 0xff, 0x7b, 0x22, 0xbc, 0x7d, 0xb9, 0x1b, 0x5b, 0xee, 0xa5, 0x95, 0xe3, 0x93, 0xf2,
14626
-	0x72, 0xdc, 0x12, 0xdd, 0x71, 0x0f, 0x5c, 0x76, 0xe4, 0xa2, 0x37, 0x20, 0x83, 0x9b, 0xed, 0xe6,
14627
-	0x53, 0x2d, 0x21, 0xc3, 0xf3, 0x1c, 0x08, 0x53, 0x97, 0x1e, 0x71, 0x4b, 0xdd, 0x66, 0xbb, 0xc1,
14628
-	0x89, 0x44, 0x72, 0x86, 0xa5, 0x2e, 0x75, 0x2d, 0xdb, 0x1d, 0xa0, 0x37, 0x21, 0xdb, 0xea, 0xf5,
14629
-	0x76, 0x44, 0x7e, 0xfc, 0xea, 0xf1, 0x49, 0xf9, 0xe6, 0x39, 0x14, 0x2f, 0x50, 0x8b, 0x83, 0x38,
14630
-	0x8b, 0xe7, 0x14, 0x63, 0x06, 0x88, 0xd3, 0x43, 0x09, 0xc2, 0x9d, 0x3e, 0x4f, 0xde, 0x33, 0x33,
14631
-	0x40, 0x98, 0xf1, 0xbf, 0x6a, 0xb9, 0xfd, 0x53, 0x12, 0xb4, 0xaa, 0x69, 0xd2, 0x51, 0xc0, 0xeb,
14632
-	0x55, 0xe2, 0xd4, 0x87, 0xdc, 0x88, 0x7f, 0xd9, 0x34, 0x24, 0x01, 0x0f, 0x67, 0x5e, 0xfd, 0x5f,
14633
-	0xd0, 0xab, 0x60, 0xe6, 0xd0, 0xaa, 0x35, 0xb4, 0x7d, 0xdf, 0x66, 0xae, 0x94, 0xe1, 0xc8, 0x52,
14634
-	0xe9, 0x3f, 0x13, 0x70, 0x73, 0x06, 0x02, 0xdd, 0x83, 0xb4, 0xc7, 0x9c, 0x70, 0x0e, 0xef, 0x5c,
14635
-	0x76, 0xb1, 0xc6, 0x55, 0xb1, 0x40, 0xa2, 0x55, 0x00, 0x32, 0x0e, 0x18, 0x11, 0xed, 0x8b, 0xd9,
14636
-	0xcb, 0xe1, 0x98, 0x04, 0x3d, 0x85, 0xac, 0x4f, 0x4d, 0x8f, 0x86, 0x54, 0xf1, 0xf3, 0xff, 0x6b,
14637
-	0xef, 0x2b, 0x3d, 0x61, 0x06, 0x2b, 0x73, 0xa5, 0x0a, 0x64, 0xa5, 0x84, 0x87, 0xbd, 0x45, 0x02,
14638
-	0x22, 0x3a, 0x5d, 0xc4, 0xe2, 0x9b, 0x47, 0x13, 0x71, 0x06, 0x61, 0x34, 0x11, 0x67, 0xa0, 0xff,
14639
-	0x75, 0x12, 0xa0, 0xf9, 0x2c, 0xa0, 0x9e, 0x4b, 0x9c, 0x7a, 0x15, 0x35, 0x63, 0xbb, 0xbf, 0x1c,
14640
-	0xed, 0xbb, 0x33, 0xaf, 0x5b, 0x23, 0x8d, 0x4a, 0xbd, 0x3a, 0x63, 0xff, 0xbf, 0x0d, 0xa9, 0xb1,
14641
-	0xa7, 0x5e, 0x73, 0x24, 0xcd, 0xdb, 0xc1, 0x5b, 0x98, 0xcb, 0x50, 0x73, 0xba, 0x6d, 0xa5, 0x2e,
14642
-	0x7f, 0xb3, 0x89, 0x35, 0x30, 0x73, 0xeb, 0xe2, 0x2b, 0xdf, 0x24, 0x86, 0x49, 0xd5, 0xc9, 0x51,
14643
-	0x94, 0x2b, 0xbf, 0x5e, 0xad, 0x53, 0x2f, 0xc0, 0x59, 0x93, 0xf0, 0xff, 0xdf, 0x6b, 0x7f, 0x7b,
14644
-	0x1f, 0x60, 0x3a, 0x34, 0xb4, 0x0a, 0x99, 0xfa, 0x46, 0xaf, 0xb7, 0xa5, 0xcd, 0xc9, 0x0d, 0x7c,
14645
-	0x5a, 0x25, 0xc4, 0xfa, 0x9f, 0x27, 0x21, 0x57, 0xaf, 0xaa, 0x63, 0xb5, 0x0e, 0x9a, 0xd8, 0x95,
14646
-	0x78, 0xef, 0x0c, 0xfa, 0x6c, 0x64, 0x7b, 0x13, 0xb5, 0xb1, 0x5c, 0x91, 0xb3, 0x2d, 0x72, 0x15,
14647
-	0xde, 0xeb, 0xa6, 0x50, 0x40, 0x18, 0x8a, 0x54, 0x39, 0xc1, 0x30, 0x49, 0xb8, 0xc7, 0xaf, 0x5e,
14648
-	0xed, 0x2c, 0xc9, 0xbe, 0xa7, 0x65, 0x1f, 0x17, 0x42, 0x23, 0x75, 0xe2, 0xa3, 0x8f, 0x61, 0xc9,
14649
-	0xb7, 0x07, 0xae, 0xed, 0x0e, 0x8c, 0xd0, 0x79, 0x29, 0xe1, 0xbc, 0x1b, 0x67, 0xa7, 0x6b, 0x0b,
14650
-	0x3d, 0x59, 0xa5, 0x7c, 0xb8, 0xa0, 0x90, 0x75, 0xe1, 0x4a, 0xf4, 0x11, 0x2c, 0xc6, 0x54, 0xb9,
14651
-	0x17, 0xa5, 0xdb, 0xb5, 0xb3, 0xd3, 0xb5, 0x62, 0xa4, 0xf9, 0x98, 0x4e, 0x70, 0x31, 0x52, 0x7c,
14652
-	0x4c, 0xc5, 0xf5, 0xc2, 0x1e, 0xf3, 0x4c, 0x6a, 0x78, 0x62, 0x4d, 0x8b, 0x13, 0x3c, 0x8d, 0x0b,
14653
-	0x42, 0x26, 0x97, 0xb9, 0xfe, 0x04, 0x6e, 0x76, 0x3c, 0x73, 0x9f, 0xfa, 0x81, 0x74, 0x85, 0xf2,
14654
-	0xe2, 0xe7, 0x70, 0x27, 0x20, 0xfe, 0x81, 0xb1, 0x6f, 0xfb, 0x01, 0xf3, 0x26, 0x86, 0x47, 0x03,
14655
-	0xea, 0xf2, 0x7a, 0x43, 0xbc, 0x48, 0xa9, 0xfb, 0x9f, 0xdb, 0x1c, 0xb3, 0x29, 0x21, 0x38, 0x44,
14656
-	0x6c, 0x71, 0x80, 0xde, 0x82, 0x22, 0x67, 0xe1, 0x0d, 0xba, 0x47, 0xc6, 0x4e, 0xc0, 0x47, 0x0f,
14657
-	0x0e, 0x1b, 0x18, 0x2f, 0x7d, 0x4c, 0xe5, 0x1d, 0x36, 0x90, 0x9f, 0xfa, 0x4f, 0x41, 0x6b, 0xd8,
14658
-	0xfe, 0x88, 0x04, 0xe6, 0x7e, 0x78, 0xb1, 0x85, 0x1a, 0xa0, 0xed, 0x53, 0xe2, 0x05, 0xbb, 0x94,
14659
-	0x04, 0xc6, 0x88, 0x7a, 0x36, 0xb3, 0xae, 0x9f, 0xe5, 0xa5, 0x48, 0xa5, 0x2b, 0x34, 0xf4, 0xff,
14660
-	0x4a, 0x00, 0x60, 0xb2, 0x17, 0x32, 0xb2, 0x1f, 0xc2, 0x0d, 0xdf, 0x25, 0x23, 0x7f, 0x9f, 0x05,
14661
-	0x86, 0xed, 0x06, 0xd4, 0x3b, 0x24, 0x8e, 0xba, 0x9f, 0xd0, 0xc2, 0x8a, 0x96, 0x92, 0xa3, 0xf7,
14662
-	0x01, 0x1d, 0x50, 0x3a, 0x32, 0x98, 0x63, 0x19, 0x61, 0xa5, 0x7c, 0x2f, 0x4b, 0x63, 0x8d, 0xd7,
14663
-	0x74, 0x1c, 0xab, 0x17, 0xca, 0x51, 0x0d, 0x56, 0xf9, 0xf0, 0xa9, 0x1b, 0x78, 0x36, 0xf5, 0x8d,
14664
-	0x3d, 0xe6, 0x19, 0xbe, 0xc3, 0x8e, 0x8c, 0x3d, 0xe6, 0x38, 0xec, 0x88, 0x7a, 0xe1, 0xd5, 0x4f,
14665
-	0xc9, 0x61, 0x83, 0xa6, 0x04, 0x6d, 0x30, 0xaf, 0xe7, 0xb0, 0xa3, 0x8d, 0x10, 0xc1, 0x69, 0xdb,
14666
-	0x74, 0xcc, 0x81, 0x6d, 0x1e, 0x84, 0xb4, 0x2d, 0x92, 0xf6, 0x6d, 0xf3, 0x00, 0xbd, 0x09, 0x0b,
14667
-	0xd4, 0xa1, 0xe2, 0x06, 0x40, 0xa2, 0x32, 0x02, 0x55, 0x0c, 0x85, 0x1c, 0xa4, 0x7f, 0x01, 0x5a,
14668
-	0xd3, 0x35, 0xbd, 0xc9, 0x28, 0x36, 0xe7, 0xef, 0x03, 0xe2, 0x9b, 0xa4, 0xe1, 0x30, 0xf3, 0xc0,
14669
-	0x18, 0x12, 0x97, 0x0c, 0x78, 0xbf, 0xe4, 0x1b, 0x8d, 0xc6, 0x6b, 0xb6, 0x98, 0x79, 0xb0, 0xad,
14670
-	0xe4, 0xfa, 0xc7, 0x00, 0xbd, 0x91, 0x47, 0x89, 0xd5, 0xe1, 0x6c, 0x82, 0xbb, 0x4e, 0x94, 0x0c,
14671
-	0x4b, 0x3d, 0x03, 0x31, 0x4f, 0x2d, 0x75, 0x4d, 0x56, 0x34, 0x22, 0xb9, 0xfe, 0xcb, 0x70, 0xb3,
14672
-	0xeb, 0x10, 0x53, 0x3c, 0x89, 0x76, 0xa3, 0x47, 0x07, 0xf4, 0x10, 0xb2, 0x12, 0xaa, 0x66, 0x72,
14673
-	0xe6, 0x72, 0x9b, 0xb6, 0xb9, 0x39, 0x87, 0x15, 0xbe, 0x56, 0x04, 0x98, 0xda, 0xd1, 0x9f, 0x41,
14674
-	0x3e, 0x32, 0x8f, 0xca, 0xc0, 0x53, 0x60, 0x1e, 0xdd, 0xb6, 0xab, 0x72, 0xd6, 0x3c, 0x8e, 0x8b,
14675
-	0x50, 0x0b, 0x0a, 0xa3, 0x48, 0xf9, 0x4a, 0x3a, 0x37, 0xa3, 0xd3, 0x38, 0xae, 0xab, 0x7f, 0x06,
14676
-	0xf0, 0x13, 0x66, 0xbb, 0x7d, 0x76, 0x40, 0x5d, 0xf1, 0xce, 0xc5, 0xb3, 0x35, 0x1a, 0x3a, 0x42,
14677
-	0x95, 0x44, 0x32, 0x2a, 0xbd, 0x18, 0x3d, 0xf7, 0xc8, 0xa2, 0xfe, 0x57, 0x49, 0xc8, 0x62, 0xc6,
14678
-	0x82, 0x7a, 0x15, 0x95, 0x21, 0xab, 0x96, 0xba, 0x38, 0x42, 0x6a, 0xf9, 0xb3, 0xd3, 0xb5, 0x8c,
14679
-	0x5c, 0xe3, 0x19, 0x53, 0x2c, 0xee, 0xd8, 0x26, 0x9c, 0xbc, 0x6c, 0x13, 0x46, 0xf7, 0xa0, 0xa8,
14680
-	0x40, 0xc6, 0x3e, 0xf1, 0xf7, 0x65, 0x8e, 0x55, 0x5b, 0x3c, 0x3b, 0x5d, 0x03, 0x89, 0xdc, 0x24,
14681
-	0xfe, 0x3e, 0x06, 0x89, 0xe6, 0xdf, 0xa8, 0x09, 0x85, 0xaf, 0x98, 0xed, 0x1a, 0x81, 0x18, 0x84,
14682
-	0xba, 0xee, 0x9a, 0x39, 0x15, 0xd3, 0xa1, 0xaa, 0x77, 0x51, 0xf8, 0x6a, 0x3a, 0xf8, 0x26, 0x2c,
14683
-	0x78, 0x8c, 0x05, 0x72, 0xe7, 0xb1, 0x99, 0xab, 0x32, 0xe9, 0xf2, 0xcc, 0x0b, 0x56, 0xc6, 0x02,
14684
-	0xac, 0x70, 0xb8, 0xe8, 0xc5, 0x4a, 0xe8, 0x1e, 0x2c, 0x3b, 0xc4, 0x0f, 0x0c, 0xb1, 0x65, 0x59,
14685
-	0x53, 0x6b, 0x59, 0xb1, 0x5a, 0x10, 0xaf, 0xdb, 0x10, 0x55, 0xa1, 0x86, 0xfe, 0x0f, 0x09, 0x28,
14686
-	0xf0, 0xc1, 0xd8, 0x7b, 0xb6, 0xc9, 0x79, 0xda, 0x77, 0xa7, 0x0f, 0xb7, 0x21, 0x65, 0xfa, 0x9e,
14687
-	0x72, 0xaa, 0x38, 0x3f, 0xeb, 0x3d, 0x8c, 0xb9, 0x0c, 0x7d, 0x01, 0x59, 0x95, 0xd1, 0x4b, 0xe6,
14688
-	0xa0, 0x5f, 0xcf, 0x28, 0x95, 0x6f, 0x94, 0x9e, 0x88, 0xc7, 0x69, 0xef, 0xe4, 0x3e, 0x8e, 0xe3,
14689
-	0x22, 0x74, 0x0b, 0x92, 0xa6, 0x74, 0x97, 0x7a, 0x78, 0xaf, 0xb7, 0x71, 0xd2, 0x74, 0xf5, 0xbf,
14690
-	0x4d, 0xc0, 0xc2, 0x74, 0xcd, 0xf2, 0x08, 0xb8, 0x03, 0x79, 0x7f, 0xbc, 0xeb, 0x4f, 0xfc, 0x80,
14691
-	0x0e, 0xc3, 0x37, 0xbc, 0x48, 0x80, 0x5a, 0x90, 0x27, 0xce, 0x80, 0x79, 0x76, 0xb0, 0x3f, 0x54,
14692
-	0xc9, 0xe4, 0xec, 0xd3, 0x3e, 0x6e, 0xb3, 0x52, 0x0d, 0x55, 0xf0, 0x54, 0x3b, 0x3c, 0xba, 0xc5,
14693
-	0x71, 0x25, 0x8f, 0xee, 0x37, 0xa0, 0xe8, 0x90, 0xa1, 0xb8, 0xe2, 0x08, 0xec, 0xa1, 0x1c, 0x47,
14694
-	0x1a, 0x17, 0x94, 0xac, 0x6f, 0x0f, 0xa9, 0xae, 0x43, 0x3e, 0x32, 0x86, 0x96, 0xa0, 0x50, 0x6d,
14695
-	0xf6, 0x8c, 0xfb, 0xeb, 0x0f, 0x8d, 0x47, 0xf5, 0x6d, 0x6d, 0x4e, 0xd1, 0xcb, 0x3f, 0x4b, 0xc0,
14696
-	0x82, 0xda, 0x51, 0x14, 0x65, 0x7f, 0x13, 0xe6, 0x3d, 0xb2, 0x17, 0x84, 0x49, 0x45, 0x5a, 0x46,
14697
-	0x35, 0xdf, 0xa4, 0x79, 0x52, 0xc1, 0xab, 0x66, 0x27, 0x15, 0xb1, 0x57, 0xe5, 0xd4, 0x95, 0xaf,
14698
-	0xca, 0xe9, 0xff, 0x97, 0x57, 0x65, 0xfd, 0x4f, 0x92, 0xb0, 0xa4, 0xd8, 0x5f, 0xb4, 0x81, 0xbd,
14699
-	0x0b, 0x79, 0x49, 0x04, 0xa7, 0x29, 0x91, 0x78, 0xc8, 0x94, 0xb8, 0x56, 0x03, 0xe7, 0x64, 0x75,
14700
-	0xcb, 0xe2, 0x39, 0xba, 0x82, 0xc6, 0x7e, 0x23, 0x01, 0x52, 0xd4, 0xe6, 0x09, 0x66, 0x03, 0xd2,
14701
-	0x7b, 0xb6, 0x43, 0x55, 0x9c, 0xcd, 0xbc, 0xbe, 0xbe, 0xd0, 0xbc, 0x78, 0x68, 0xe9, 0x8b, 0x2c,
14702
-	0x7f, 0x73, 0x0e, 0x0b, 0xed, 0xd2, 0x6f, 0x02, 0x4c, 0xa5, 0x33, 0x13, 0x59, 0x4e, 0x16, 0xd5,
14703
-	0x9d, 0x60, 0x48, 0x16, 0x5b, 0x0d, 0xcc, 0x65, 0xbc, 0x6a, 0x60, 0x5b, 0x6a, 0xcb, 0x10, 0x55,
14704
-	0x8f, 0x78, 0xd5, 0xc0, 0xb6, 0xa2, 0xd7, 0x9e, 0xf4, 0x35, 0xaf, 0x3d, 0xb5, 0x5c, 0x78, 0x33,
14705
-	0xa5, 0x6f, 0xc1, 0xad, 0x9a, 0x43, 0xcc, 0x03, 0xc7, 0xf6, 0x03, 0x6a, 0xc5, 0x57, 0xe8, 0x3a,
14706
-	0x64, 0xcf, 0xf1, 0xb4, 0xab, 0x2e, 0x02, 0x15, 0x52, 0xff, 0xb7, 0x04, 0x14, 0x37, 0x29, 0x71,
14707
-	0x82, 0xfd, 0xe9, 0x6d, 0x4a, 0x40, 0xfd, 0x40, 0x6d, 0xf0, 0xe2, 0x1b, 0x7d, 0x08, 0xb9, 0xe8,
14708
-	0x18, 0xbf, 0xf6, 0x45, 0x26, 0x82, 0xa2, 0x07, 0x30, 0xcf, 0x63, 0x9a, 0x8d, 0xc3, 0xfc, 0xe0,
14709
-	0xaa, 0xcb, 0x7e, 0x85, 0xe4, 0x9b, 0xba, 0x47, 0xc5, 0xb9, 0x2d, 0x9c, 0x92, 0xc1, 0x61, 0x11,
14710
-	0xfd, 0x12, 0x14, 0xc5, 0x5d, 0x75, 0x48, 0x53, 0x32, 0xd7, 0xd9, 0x2c, 0xc8, 0xe7, 0x26, 0x49,
14711
-	0x51, 0xfe, 0x27, 0x01, 0xcb, 0xdb, 0x64, 0xb2, 0x4b, 0xd5, 0x32, 0xa5, 0x16, 0xa6, 0x26, 0xf3,
14712
-	0x2c, 0xd4, 0x8d, 0x2f, 0xef, 0x2b, 0x5e, 0xaf, 0x66, 0x29, 0xcf, 0x5e, 0xe5, 0x61, 0xce, 0x92,
14713
-	0x8c, 0xe5, 0x2c, 0xcb, 0x90, 0x71, 0x99, 0x6b, 0x52, 0xb5, 0xf6, 0x65, 0x41, 0xb7, 0xe3, 0x4b,
14714
-	0xbb, 0x14, 0x3d, 0x2c, 0x89, 0x67, 0xa1, 0x36, 0x0b, 0xa2, 0xd6, 0xd0, 0x17, 0x50, 0xea, 0x35,
14715
-	0xeb, 0xb8, 0xd9, 0xaf, 0x75, 0x7e, 0x6a, 0xf4, 0xaa, 0x5b, 0xbd, 0xea, 0xfa, 0x3d, 0xa3, 0xdb,
14716
-	0xd9, 0xfa, 0xf2, 0xfe, 0x83, 0x7b, 0x1f, 0x6a, 0x89, 0x52, 0xf9, 0xf8, 0xa4, 0x7c, 0xa7, 0x5d,
14717
-	0xad, 0x6f, 0xc9, 0x58, 0xde, 0x65, 0xcf, 0x7a, 0xc4, 0xf1, 0xc9, 0xfa, 0xbd, 0x2e, 0x73, 0x26,
14718
-	0x1c, 0xa3, 0x9f, 0x24, 0xa0, 0x18, 0x3f, 0x1f, 0xe2, 0xc7, 0x5e, 0xe2, 0xd2, 0x63, 0x6f, 0x7a,
14719
-	0x7a, 0x26, 0x2f, 0x39, 0x3d, 0x37, 0x60, 0xd9, 0xf4, 0x98, 0xef, 0x1b, 0x9c, 0x30, 0x53, 0xeb,
14720
-	0x02, 0x25, 0x7f, 0xe5, 0xec, 0x74, 0xed, 0x46, 0x9d, 0xd7, 0xf7, 0x44, 0xb5, 0x32, 0x7f, 0xc3,
14721
-	0x8c, 0x89, 0x44, 0x4b, 0xef, 0xfd, 0x22, 0x05, 0xf9, 0xe8, 0xba, 0x99, 0x2f, 0x19, 0x9e, 0xeb,
14722
-	0x2b, 0x57, 0x44, 0xf2, 0x36, 0x3d, 0x42, 0x6f, 0x4c, 0xb3, 0xfc, 0x2f, 0xe4, 0xfb, 0x5a, 0x54,
14723
-	0x1d, 0x66, 0xf8, 0x6f, 0x41, 0xae, 0xda, 0xeb, 0xb5, 0x1e, 0xb5, 0x9b, 0x0d, 0xed, 0xeb, 0x44,
14724
-	0xe9, 0x95, 0xe3, 0x93, 0xf2, 0x8d, 0x08, 0x54, 0xf5, 0x65, 0x4f, 0x05, 0xaa, 0x5e, 0x6f, 0x76,
14725
-	0xfb, 0xcd, 0x86, 0xf6, 0x3c, 0x79, 0x11, 0x25, 0xb2, 0x56, 0xf1, 0x4a, 0x9e, 0xef, 0xe2, 0x66,
14726
-	0xb7, 0x8a, 0x79, 0x83, 0x5f, 0x27, 0xe5, 0xe5, 0xc3, 0xb4, 0x45, 0x8f, 0x8e, 0x88, 0xc7, 0xdb,
14727
-	0x5c, 0x0d, 0x7f, 0x2d, 0xf2, 0x3c, 0x25, 0x5f, 0x52, 0xa7, 0x77, 0xe7, 0x94, 0x58, 0x13, 0xde,
14728
-	0x9a, 0x78, 0xb4, 0x10, 0x66, 0x52, 0x17, 0x5a, 0xeb, 0xf1, 0x40, 0xe5, 0x56, 0x74, 0x98, 0xc7,
14729
-	0x3b, 0xed, 0x36, 0x07, 0x3d, 0x4f, 0x5f, 0x18, 0x1d, 0x1e, 0xbb, 0x3c, 0x23, 0x41, 0x77, 0x21,
14730
-	0x17, 0xbe, 0x69, 0x68, 0x5f, 0xa7, 0x2f, 0x74, 0xa8, 0x1e, 0x3e, 0xc8, 0x88, 0x06, 0x37, 0x77,
14731
-	0xfa, 0xe2, 0xc7, 0x2c, 0xcf, 0x33, 0x17, 0x1b, 0xdc, 0x1f, 0x07, 0x16, 0x3b, 0x72, 0xf9, 0x04,
14732
-	0xab, 0x7b, 0x8e, 0xaf, 0x33, 0x32, 0x29, 0x8c, 0x30, 0xea, 0x92, 0xe3, 0x2d, 0xc8, 0xe1, 0xe6,
14733
-	0x4f, 0xe4, 0xef, 0x5e, 0x9e, 0x67, 0x2f, 0xd8, 0xc1, 0xf4, 0x2b, 0x6a, 0xaa, 0xd6, 0x3a, 0xb8,
14734
-	0xbb, 0x59, 0x15, 0x2e, 0xbf, 0x88, 0xea, 0x78, 0xa3, 0x7d, 0xe2, 0x52, 0x6b, 0xfa, 0x9c, 0x1c,
14735
-	0x55, 0xbd, 0xf7, 0x2b, 0x90, 0x0b, 0x69, 0x03, 0x5a, 0x85, 0xec, 0xd3, 0x0e, 0x7e, 0xdc, 0xc4,
14736
-	0xda, 0x9c, 0xf4, 0x61, 0x58, 0xf3, 0x54, 0x12, 0xbe, 0x32, 0xcc, 0x6f, 0x57, 0xdb, 0xd5, 0x47,
14737
-	0x4d, 0x1c, 0x5e, 0x41, 0x86, 0x00, 0x75, 0xf6, 0x95, 0x34, 0xd5, 0x40, 0x64, 0xb3, 0xb6, 0xf2,
14738
-	0xcd, 0xb7, 0xab, 0x73, 0x3f, 0xff, 0x76, 0x75, 0xee, 0xf9, 0xd9, 0x6a, 0xe2, 0x9b, 0xb3, 0xd5,
14739
-	0xc4, 0xcf, 0xce, 0x56, 0x13, 0xff, 0x72, 0xb6, 0x9a, 0xd8, 0xcd, 0x8a, 0x1d, 0xe3, 0xc1, 0xff,
14740
-	0x06, 0x00, 0x00, 0xff, 0xff, 0x45, 0x07, 0xa3, 0xee, 0x6e, 0x2a, 0x00, 0x00,
14469
+	// 4643 bytes of a gzipped FileDescriptorProto
14470
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x5a, 0x4d, 0x6c, 0x23, 0x47,
14471
+	0x76, 0x16, 0x7f, 0x45, 0x3e, 0x52, 0x52, 0x4f, 0x8d, 0x76, 0x56, 0xc3, 0x1d, 0x4b, 0x74, 0xdb,
14472
+	0xb3, 0xf6, 0x7a, 0x1d, 0x7a, 0x7e, 0x76, 0x17, 0x63, 0x3b, 0x6b, 0x9b, 0x7f, 0x1a, 0x71, 0x47,
14473
+	0x22, 0x89, 0x22, 0x35, 0xb3, 0x3e, 0x24, 0x8d, 0x56, 0x77, 0x89, 0x6a, 0xab, 0xd9, 0xc5, 0x74,
14474
+	0x17, 0xa5, 0x61, 0x7e, 0x90, 0x41, 0x0e, 0x49, 0xa0, 0x53, 0x72, 0x0b, 0x10, 0x28, 0x97, 0xe4,
14475
+	0x14, 0xe4, 0x96, 0x43, 0x90, 0x5c, 0xe2, 0x00, 0x39, 0xf8, 0x96, 0x4d, 0x02, 0x04, 0x8b, 0x04,
14476
+	0x50, 0x62, 0x1d, 0x72, 0x0b, 0x92, 0xcb, 0x22, 0x97, 0x04, 0x08, 0xea, 0xa7, 0x9b, 0x4d, 0x0d,
14477
+	0x25, 0x8d, 0xe3, 0xbd, 0x48, 0x5d, 0xef, 0x7d, 0xef, 0xd5, 0xab, 0x57, 0xaf, 0xaa, 0xde, 0xab,
14478
+	0x22, 0x14, 0xd8, 0x64, 0x44, 0x82, 0xca, 0xc8, 0xa7, 0x8c, 0x22, 0x64, 0x53, 0xeb, 0x90, 0xf8,
14479
+	0x95, 0xe0, 0xd8, 0xf4, 0x87, 0x87, 0x0e, 0xab, 0x1c, 0xdd, 0x2f, 0x6d, 0x0c, 0x28, 0x1d, 0xb8,
14480
+	0xe4, 0x3d, 0x81, 0xd8, 0x1b, 0xef, 0xbf, 0xc7, 0x9c, 0x21, 0x09, 0x98, 0x39, 0x1c, 0x49, 0xa1,
14481
+	0xd2, 0xfa, 0x45, 0x80, 0x3d, 0xf6, 0x4d, 0xe6, 0x50, 0x4f, 0xf1, 0x57, 0x07, 0x74, 0x40, 0xc5,
14482
+	0xe7, 0x7b, 0xfc, 0x4b, 0x52, 0xf5, 0x0d, 0x58, 0x7c, 0x4a, 0xfc, 0xc0, 0xa1, 0x1e, 0x5a, 0x85,
14483
+	0x8c, 0xe3, 0xd9, 0xe4, 0xf9, 0x5a, 0xa2, 0x9c, 0x78, 0x3b, 0x8d, 0x65, 0x43, 0xbf, 0x07, 0xd0,
14484
+	0xe2, 0x1f, 0x4d, 0x8f, 0xf9, 0x13, 0xa4, 0x41, 0xea, 0x90, 0x4c, 0x04, 0x22, 0x8f, 0xf9, 0x27,
14485
+	0xa7, 0x1c, 0x99, 0xee, 0x5a, 0x52, 0x52, 0x8e, 0x4c, 0x57, 0xff, 0x32, 0x01, 0x85, 0xaa, 0xe7,
14486
+	0x51, 0x26, 0x7a, 0x0f, 0x10, 0x82, 0xb4, 0x67, 0x0e, 0x89, 0x12, 0x12, 0xdf, 0xa8, 0x0e, 0x59,
14487
+	0xd7, 0xdc, 0x23, 0x6e, 0xb0, 0x96, 0x2c, 0xa7, 0xde, 0x2e, 0x3c, 0xf8, 0x6e, 0xe5, 0xe5, 0x21,
14488
+	0x57, 0x62, 0x4a, 0x2a, 0xdb, 0x02, 0x2d, 0x8c, 0xc0, 0x4a, 0x14, 0x7d, 0x04, 0x8b, 0x8e, 0x67,
14489
+	0x3b, 0x16, 0x09, 0xd6, 0xd2, 0x42, 0xcb, 0xfa, 0x3c, 0x2d, 0x53, 0xeb, 0x6b, 0xe9, 0x2f, 0xce,
14490
+	0x36, 0x16, 0x70, 0x28, 0x54, 0x7a, 0x1f, 0x0a, 0x31, 0xb5, 0x73, 0xc6, 0xb6, 0x0a, 0x99, 0x23,
14491
+	0xd3, 0x1d, 0x13, 0x35, 0x3a, 0xd9, 0xf8, 0x20, 0xf9, 0x28, 0xa1, 0x7f, 0x0a, 0x79, 0x4c, 0x02,
14492
+	0x3a, 0xf6, 0x2d, 0x12, 0xa0, 0xef, 0x40, 0xde, 0x33, 0x3d, 0x6a, 0x58, 0xa3, 0x71, 0x20, 0xc4,
14493
+	0x53, 0xb5, 0xe2, 0xf9, 0xd9, 0x46, 0xae, 0x6d, 0x7a, 0xb4, 0xde, 0xdd, 0x0d, 0x70, 0x8e, 0xb3,
14494
+	0xeb, 0xa3, 0x71, 0x80, 0x5e, 0x87, 0xe2, 0x90, 0x0c, 0xa9, 0x3f, 0x31, 0xf6, 0x26, 0x8c, 0x04,
14495
+	0x42, 0x71, 0x0a, 0x17, 0x24, 0xad, 0xc6, 0x49, 0xfa, 0xef, 0x25, 0x60, 0x35, 0xd4, 0x8d, 0xc9,
14496
+	0xaf, 0x8c, 0x1d, 0x9f, 0x0c, 0x89, 0xc7, 0x02, 0xf4, 0x7d, 0xc8, 0xba, 0xce, 0xd0, 0x61, 0xb2,
14497
+	0x8f, 0xc2, 0x83, 0xd7, 0xe6, 0x8d, 0x36, 0xb2, 0x0a, 0x2b, 0x30, 0xaa, 0x42, 0xd1, 0x27, 0x01,
14498
+	0xf1, 0x8f, 0xa4, 0x27, 0x45, 0x97, 0xd7, 0x0a, 0xcf, 0x88, 0xe8, 0x9b, 0x90, 0xeb, 0xba, 0x26,
14499
+	0xdb, 0xa7, 0xfe, 0x10, 0xe9, 0x50, 0x34, 0x7d, 0xeb, 0xc0, 0x61, 0xc4, 0x62, 0x63, 0x3f, 0x9c,
14500
+	0xd5, 0x19, 0x1a, 0xba, 0x05, 0x49, 0x2a, 0x3b, 0xca, 0xd7, 0xb2, 0xe7, 0x67, 0x1b, 0xc9, 0x4e,
14501
+	0x0f, 0x27, 0x69, 0xa0, 0x7f, 0x08, 0x37, 0xba, 0xee, 0x78, 0xe0, 0x78, 0x0d, 0x12, 0x58, 0xbe,
14502
+	0x33, 0xe2, 0xda, 0x79, 0x78, 0xf0, 0xd8, 0x0f, 0xc3, 0x83, 0x7f, 0x47, 0x21, 0x93, 0x9c, 0x86,
14503
+	0x8c, 0xfe, 0x3b, 0x49, 0xb8, 0xd1, 0xf4, 0x06, 0x8e, 0x47, 0xe2, 0xd2, 0x77, 0x61, 0x99, 0x08,
14504
+	0xa2, 0x71, 0x24, 0xc3, 0x58, 0xe9, 0x59, 0x92, 0xd4, 0x30, 0xb6, 0x5b, 0x17, 0xe2, 0xed, 0xfe,
14505
+	0xbc, 0xe1, 0xbf, 0xa4, 0x7d, 0x6e, 0xd4, 0x35, 0x61, 0x71, 0x24, 0x06, 0x11, 0xac, 0xa5, 0x84,
14506
+	0xae, 0xbb, 0xf3, 0x74, 0xbd, 0x34, 0xce, 0x30, 0xf8, 0x94, 0xec, 0xd7, 0x09, 0xbe, 0x3f, 0x4b,
14507
+	0xc2, 0x4a, 0x9b, 0xda, 0x33, 0x7e, 0x28, 0x41, 0xee, 0x80, 0x06, 0x2c, 0xb6, 0xd0, 0xa2, 0x36,
14508
+	0x7a, 0x04, 0xb9, 0x91, 0x9a, 0x3e, 0x35, 0xfb, 0x77, 0xe6, 0x9b, 0x2c, 0x31, 0x38, 0x42, 0xa3,
14509
+	0x0f, 0x21, 0xef, 0x87, 0x31, 0xb1, 0x96, 0x7a, 0x95, 0xc0, 0x99, 0xe2, 0xd1, 0x0f, 0x21, 0x2b,
14510
+	0x27, 0x61, 0x2d, 0x2d, 0x24, 0xef, 0xbe, 0x92, 0xcf, 0xb1, 0x12, 0x42, 0x8f, 0x21, 0xc7, 0xdc,
14511
+	0xc0, 0x70, 0xbc, 0x7d, 0xba, 0x96, 0x11, 0x0a, 0x36, 0xe6, 0x29, 0xe0, 0x8e, 0xe8, 0x6f, 0xf7,
14512
+	0x5a, 0xde, 0x3e, 0xad, 0x15, 0xce, 0xcf, 0x36, 0x16, 0x55, 0x03, 0x2f, 0x32, 0x37, 0xe0, 0x1f,
14513
+	0xfa, 0xef, 0x27, 0xa0, 0x10, 0x43, 0xa1, 0xd7, 0x00, 0x98, 0x3f, 0x0e, 0x98, 0xe1, 0x53, 0xca,
14514
+	0x84, 0xb3, 0x8a, 0x38, 0x2f, 0x28, 0x98, 0x52, 0x86, 0x2a, 0x70, 0xd3, 0x22, 0x3e, 0x33, 0x9c,
14515
+	0x20, 0x18, 0x13, 0xdf, 0x08, 0xc6, 0x7b, 0x9f, 0x11, 0x8b, 0x09, 0xc7, 0x15, 0xf1, 0x0d, 0xce,
14516
+	0x6a, 0x09, 0x4e, 0x4f, 0x32, 0xd0, 0x43, 0xb8, 0x15, 0xc7, 0x8f, 0xc6, 0x7b, 0xae, 0x63, 0x19,
14517
+	0x7c, 0x32, 0x53, 0x42, 0xe4, 0xe6, 0x54, 0xa4, 0x2b, 0x78, 0x4f, 0xc8, 0x44, 0xff, 0x69, 0x02,
14518
+	0x34, 0x6c, 0xee, 0xb3, 0x1d, 0x32, 0xdc, 0x23, 0x7e, 0x8f, 0x99, 0x6c, 0x1c, 0xa0, 0x5b, 0x90,
14519
+	0x75, 0x89, 0x69, 0x13, 0x5f, 0x18, 0x95, 0xc3, 0xaa, 0x85, 0x76, 0xf9, 0x0a, 0x36, 0xad, 0x03,
14520
+	0x73, 0xcf, 0x71, 0x1d, 0x36, 0x11, 0xa6, 0x2c, 0xcf, 0x0f, 0xe1, 0x8b, 0x3a, 0x2b, 0x38, 0x26,
14521
+	0x88, 0x67, 0xd4, 0xa0, 0x35, 0x58, 0x1c, 0x92, 0x20, 0x30, 0x07, 0x44, 0x58, 0x9a, 0xc7, 0x61,
14522
+	0x53, 0xff, 0x10, 0x8a, 0x71, 0x39, 0x54, 0x80, 0xc5, 0xdd, 0xf6, 0x93, 0x76, 0xe7, 0x59, 0x5b,
14523
+	0x5b, 0x40, 0x2b, 0x50, 0xd8, 0x6d, 0xe3, 0x66, 0xb5, 0xbe, 0x55, 0xad, 0x6d, 0x37, 0xb5, 0x04,
14524
+	0x5a, 0x82, 0xfc, 0xb4, 0x99, 0xd4, 0xff, 0x3c, 0x01, 0xc0, 0xdd, 0xad, 0x06, 0xf5, 0x01, 0x64,
14525
+	0x02, 0x66, 0x32, 0x19, 0x95, 0xcb, 0x0f, 0xde, 0xbc, 0x6c, 0x0e, 0x95, 0xbd, 0xfc, 0x1f, 0xc1,
14526
+	0x52, 0x24, 0x6e, 0x61, 0x72, 0xc6, 0x42, 0xbe, 0x41, 0x98, 0xb6, 0xed, 0x2b, 0xc3, 0xc5, 0xb7,
14527
+	0xfe, 0x21, 0x64, 0x84, 0xf4, 0xac, 0xb9, 0x39, 0x48, 0x37, 0xf8, 0x57, 0x02, 0xe5, 0x21, 0x83,
14528
+	0x9b, 0xd5, 0xc6, 0xa7, 0x5a, 0x12, 0x69, 0x50, 0x6c, 0xb4, 0x7a, 0xf5, 0x4e, 0xbb, 0xdd, 0xac,
14529
+	0xf7, 0x9b, 0x0d, 0x2d, 0xa5, 0xdf, 0x85, 0x4c, 0x6b, 0xc8, 0x35, 0xdf, 0xe1, 0x21, 0xbf, 0x4f,
14530
+	0x7c, 0xe2, 0x59, 0xe1, 0x4a, 0x9a, 0x12, 0xf4, 0x9f, 0xe4, 0x21, 0xb3, 0x43, 0xc7, 0x1e, 0x43,
14531
+	0x0f, 0x62, 0xdb, 0xd6, 0xf2, 0xfc, 0x93, 0x47, 0x00, 0x2b, 0xfd, 0xc9, 0x88, 0xa8, 0x6d, 0xed,
14532
+	0x16, 0x64, 0xe5, 0xe2, 0x50, 0xc3, 0x51, 0x2d, 0x4e, 0x67, 0xa6, 0x3f, 0x20, 0x4c, 0x8d, 0x47,
14533
+	0xb5, 0xd0, 0xdb, 0x90, 0xf3, 0x89, 0x69, 0x53, 0xcf, 0x9d, 0x88, 0x35, 0x94, 0x93, 0xe7, 0x0a,
14534
+	0x26, 0xa6, 0xdd, 0xf1, 0xdc, 0x09, 0x8e, 0xb8, 0x68, 0x0b, 0x8a, 0x7b, 0x8e, 0x67, 0x1b, 0x74,
14535
+	0x24, 0x37, 0xf9, 0xcc, 0xe5, 0x2b, 0x4e, 0x5a, 0x55, 0x73, 0x3c, 0xbb, 0x23, 0xc1, 0xb8, 0xb0,
14536
+	0x37, 0x6d, 0xa0, 0x36, 0x2c, 0x1f, 0x51, 0x77, 0x3c, 0x24, 0x91, 0xae, 0xac, 0xd0, 0xf5, 0xd6,
14537
+	0xe5, 0xba, 0x9e, 0x0a, 0x7c, 0xa8, 0x6d, 0xe9, 0x28, 0xde, 0x44, 0x4f, 0x60, 0x89, 0x0d, 0x47,
14538
+	0xfb, 0x41, 0xa4, 0x6e, 0x51, 0xa8, 0xfb, 0xf6, 0x15, 0x0e, 0xe3, 0xf0, 0x50, 0x5b, 0x91, 0xc5,
14539
+	0x5a, 0xa5, 0xdf, 0x4a, 0x41, 0x21, 0x66, 0x39, 0xea, 0x41, 0x61, 0xe4, 0xd3, 0x91, 0x39, 0x10,
14540
+	0x07, 0x95, 0x9a, 0x8b, 0xfb, 0xaf, 0x34, 0xea, 0x4a, 0x77, 0x2a, 0x88, 0xe3, 0x5a, 0xf4, 0xd3,
14541
+	0x24, 0x14, 0x62, 0x4c, 0xf4, 0x0e, 0xe4, 0x70, 0x17, 0xb7, 0x9e, 0x56, 0xfb, 0x4d, 0x6d, 0xa1,
14542
+	0x74, 0xe7, 0xe4, 0xb4, 0xbc, 0x26, 0xb4, 0xc5, 0x15, 0x74, 0x7d, 0xe7, 0x88, 0x87, 0xde, 0xdb,
14543
+	0xb0, 0x18, 0x42, 0x13, 0xa5, 0x6f, 0x9d, 0x9c, 0x96, 0xbf, 0x79, 0x11, 0x1a, 0x43, 0xe2, 0xde,
14544
+	0x56, 0x15, 0x37, 0x1b, 0x5a, 0x72, 0x3e, 0x12, 0xf7, 0x0e, 0x4c, 0x9f, 0xd8, 0xe8, 0xdb, 0x90,
14545
+	0x55, 0xc0, 0x54, 0xa9, 0x74, 0x72, 0x5a, 0xbe, 0x75, 0x11, 0x38, 0xc5, 0xe1, 0xde, 0x76, 0xf5,
14546
+	0x69, 0x53, 0x4b, 0xcf, 0xc7, 0xe1, 0x9e, 0x6b, 0x1e, 0x11, 0xf4, 0x26, 0x64, 0x24, 0x2c, 0x53,
14547
+	0xba, 0x7d, 0x72, 0x5a, 0xfe, 0xc6, 0x4b, 0xea, 0x38, 0xaa, 0xb4, 0xf6, 0xbb, 0x7f, 0xbc, 0xbe,
14548
+	0xf0, 0x57, 0x7f, 0xb2, 0xae, 0x5d, 0x64, 0x97, 0xfe, 0x27, 0x01, 0x4b, 0x33, 0x53, 0x8e, 0x74,
14549
+	0xc8, 0x7a, 0xd4, 0xa2, 0x23, 0x79, 0x7e, 0xe5, 0x6a, 0x70, 0x7e, 0xb6, 0x91, 0x6d, 0xd3, 0x3a,
14550
+	0x1d, 0x4d, 0xb0, 0xe2, 0xa0, 0x27, 0x17, 0x4e, 0xe0, 0x87, 0xaf, 0x18, 0x4f, 0x73, 0xcf, 0xe0,
14551
+	0x8f, 0x61, 0xc9, 0xf6, 0x9d, 0x23, 0xe2, 0x1b, 0x16, 0xf5, 0xf6, 0x9d, 0x81, 0x3a, 0x9b, 0x4a,
14552
+	0xf3, 0x74, 0x36, 0x04, 0x10, 0x17, 0xa5, 0x40, 0x5d, 0xe0, 0xbf, 0xc6, 0xe9, 0x5b, 0x7a, 0x0a,
14553
+	0xc5, 0x78, 0x84, 0xf2, 0xe3, 0x24, 0x70, 0x7e, 0x95, 0xa8, 0x84, 0x4e, 0xa4, 0x7f, 0x38, 0xcf,
14554
+	0x29, 0x22, 0x9d, 0x43, 0x6f, 0x41, 0x7a, 0x48, 0x6d, 0xa9, 0x67, 0xa9, 0x76, 0x93, 0x27, 0x01,
14555
+	0xff, 0x7c, 0xb6, 0x51, 0xa0, 0x41, 0x65, 0xd3, 0x71, 0xc9, 0x0e, 0xb5, 0x09, 0x16, 0x00, 0xfd,
14556
+	0x08, 0xd2, 0x7c, 0xab, 0x40, 0xdf, 0x82, 0x74, 0xad, 0xd5, 0x6e, 0x68, 0x0b, 0xa5, 0x1b, 0x27,
14557
+	0xa7, 0xe5, 0x25, 0xe1, 0x12, 0xce, 0xe0, 0xb1, 0x8b, 0x36, 0x20, 0xfb, 0xb4, 0xb3, 0xbd, 0xbb,
14558
+	0xc3, 0xc3, 0xeb, 0xe6, 0xc9, 0x69, 0x79, 0x25, 0x62, 0x4b, 0xa7, 0xa1, 0xd7, 0x20, 0xd3, 0xdf,
14559
+	0xe9, 0x6e, 0xf6, 0xb4, 0x64, 0x09, 0x9d, 0x9c, 0x96, 0x97, 0x23, 0xbe, 0xb0, 0xb9, 0x74, 0x43,
14560
+	0xcd, 0x6a, 0x3e, 0xa2, 0xeb, 0x3f, 0x4b, 0xc2, 0x12, 0xe6, 0x95, 0x84, 0xcf, 0xba, 0xd4, 0x75,
14561
+	0xac, 0x09, 0xea, 0x42, 0xde, 0xa2, 0x9e, 0xed, 0xc4, 0xd6, 0xd4, 0x83, 0x4b, 0x4e, 0xfd, 0xa9,
14562
+	0x54, 0xd8, 0xaa, 0x87, 0x92, 0x78, 0xaa, 0x04, 0xbd, 0x07, 0x19, 0x9b, 0xb8, 0xe6, 0x44, 0xa5,
14563
+	0x1f, 0xb7, 0x2b, 0xb2, 0x56, 0xa9, 0x84, 0xb5, 0x4a, 0xa5, 0xa1, 0x6a, 0x15, 0x2c, 0x71, 0x22,
14564
+	0x4f, 0x36, 0x9f, 0x1b, 0x26, 0x63, 0x64, 0x38, 0x62, 0x32, 0xf7, 0x48, 0xe3, 0xc2, 0xd0, 0x7c,
14565
+	0x5e, 0x55, 0x24, 0x74, 0x1f, 0xb2, 0xc7, 0x8e, 0x67, 0xd3, 0x63, 0x95, 0x5e, 0x5c, 0xa1, 0x54,
14566
+	0x01, 0xf5, 0x13, 0x7e, 0xea, 0x5e, 0x30, 0x93, 0xfb, 0xbb, 0xdd, 0x69, 0x37, 0x43, 0x7f, 0x2b,
14567
+	0x7e, 0xc7, 0x6b, 0x53, 0x8f, 0xaf, 0x15, 0xe8, 0xb4, 0x8d, 0xcd, 0x6a, 0x6b, 0x7b, 0x17, 0x73,
14568
+	0x9f, 0xaf, 0x9e, 0x9c, 0x96, 0xb5, 0x08, 0xb2, 0x69, 0x3a, 0x2e, 0xcf, 0x77, 0x6f, 0x43, 0xaa,
14569
+	0xda, 0xfe, 0x54, 0x4b, 0x96, 0xb4, 0x93, 0xd3, 0x72, 0x31, 0x62, 0x57, 0xbd, 0xc9, 0x74, 0x19,
14570
+	0x5d, 0xec, 0x57, 0xff, 0xbb, 0x14, 0x14, 0x77, 0x47, 0xb6, 0xc9, 0x88, 0x8c, 0x49, 0x54, 0x86,
14571
+	0xc2, 0xc8, 0xf4, 0x4d, 0xd7, 0x25, 0xae, 0x13, 0x0c, 0x55, 0x15, 0x16, 0x27, 0xa1, 0xf7, 0x5f,
14572
+	0xd5, 0x8d, 0xb5, 0x1c, 0x8f, 0xb3, 0x3f, 0xf8, 0xd7, 0x8d, 0x44, 0xe8, 0xd0, 0x5d, 0x58, 0xde,
14573
+	0x97, 0xd6, 0x1a, 0xa6, 0x25, 0x26, 0x36, 0x25, 0x26, 0xb6, 0x32, 0x6f, 0x62, 0xe3, 0x66, 0x55,
14574
+	0xd4, 0x20, 0xab, 0x42, 0x0a, 0x2f, 0xed, 0xc7, 0x9b, 0xe8, 0x21, 0x2c, 0x0e, 0xa9, 0xe7, 0x30,
14575
+	0xea, 0x5f, 0x3f, 0x0b, 0x21, 0x12, 0xbd, 0x03, 0x37, 0xf8, 0xe4, 0x86, 0xf6, 0x08, 0xb6, 0x38,
14576
+	0xb1, 0x92, 0x78, 0x65, 0x68, 0x3e, 0x57, 0x1d, 0x62, 0x4e, 0x46, 0x35, 0xc8, 0x50, 0x9f, 0xa7,
14577
+	0x44, 0x59, 0x61, 0xee, 0xbb, 0xd7, 0x9a, 0x2b, 0x1b, 0x1d, 0x2e, 0x83, 0xa5, 0xa8, 0xfe, 0x03,
14578
+	0x58, 0x9a, 0x19, 0x04, 0xcf, 0x04, 0xba, 0xd5, 0xdd, 0x5e, 0x53, 0x5b, 0x40, 0x45, 0xc8, 0xd5,
14579
+	0x3b, 0xed, 0x7e, 0xab, 0xbd, 0xcb, 0x53, 0x99, 0x22, 0xe4, 0x70, 0x67, 0x7b, 0xbb, 0x56, 0xad,
14580
+	0x3f, 0xd1, 0x92, 0x7a, 0x05, 0x0a, 0x31, 0x6d, 0x68, 0x19, 0xa0, 0xd7, 0xef, 0x74, 0x8d, 0xcd,
14581
+	0x16, 0xee, 0xf5, 0x65, 0x22, 0xd4, 0xeb, 0x57, 0x71, 0x5f, 0x11, 0x12, 0xfa, 0x7f, 0x26, 0xc3,
14582
+	0x19, 0x55, 0xb9, 0x4f, 0x6d, 0x36, 0xf7, 0xb9, 0xc2, 0x78, 0x95, 0xfd, 0x4c, 0x1b, 0x51, 0x0e,
14583
+	0xf4, 0x3e, 0x80, 0x08, 0x1c, 0x62, 0x1b, 0x26, 0x53, 0x13, 0x5f, 0x7a, 0xc9, 0xc9, 0xfd, 0xf0,
14584
+	0x32, 0x00, 0xe7, 0x15, 0xba, 0xca, 0xd0, 0x0f, 0xa1, 0x68, 0xd1, 0xe1, 0xc8, 0x25, 0x4a, 0x38,
14585
+	0x75, 0xad, 0x70, 0x21, 0xc2, 0x57, 0x59, 0x3c, 0xfb, 0x4a, 0xcf, 0xe6, 0x87, 0xbf, 0x9d, 0x08,
14586
+	0x3d, 0x33, 0x27, 0xe1, 0x2a, 0x42, 0x6e, 0xb7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0xc7, 0x5a, 0x02,
14587
+	0x01, 0x64, 0x85, 0xab, 0x1b, 0x5a, 0x92, 0x27, 0x8a, 0xf5, 0xce, 0x4e, 0x77, 0xbb, 0x29, 0x52,
14588
+	0x2e, 0xb4, 0x0a, 0x5a, 0xe8, 0x6c, 0x43, 0x38, 0xb2, 0xd9, 0xd0, 0xd2, 0xe8, 0x26, 0xac, 0x44,
14589
+	0x54, 0x25, 0x99, 0x41, 0xb7, 0x00, 0x45, 0xc4, 0xa9, 0x8a, 0xac, 0xfe, 0x1b, 0xb0, 0x52, 0xa7,
14590
+	0x1e, 0x33, 0x1d, 0x2f, 0x4a, 0xa2, 0x1f, 0xf0, 0x41, 0x2b, 0x92, 0xe1, 0xd8, 0x72, 0x4f, 0xaf,
14591
+	0xad, 0x9c, 0x9f, 0x6d, 0x14, 0x22, 0x68, 0xab, 0xc1, 0x47, 0x1a, 0x36, 0x6c, 0xbe, 0x7e, 0x47,
14592
+	0x8e, 0x2d, 0x9c, 0x9b, 0xa9, 0x2d, 0x9e, 0x9f, 0x6d, 0xa4, 0xba, 0xad, 0x06, 0xe6, 0x34, 0xf4,
14593
+	0x2d, 0xc8, 0x93, 0xe7, 0x0e, 0x33, 0x2c, 0xbe, 0x87, 0x73, 0x07, 0x66, 0x70, 0x8e, 0x13, 0xea,
14594
+	0x7c, 0xcb, 0xae, 0x01, 0x74, 0xa9, 0xcf, 0x54, 0xcf, 0xdf, 0x83, 0xcc, 0x88, 0xfa, 0xa2, 0x3c,
14595
+	0xbf, 0xf4, 0x32, 0x82, 0xc3, 0x65, 0xa0, 0x62, 0x09, 0xd6, 0xff, 0x3a, 0x09, 0xd0, 0x37, 0x83,
14596
+	0x43, 0xa5, 0xe4, 0x11, 0xe4, 0xa3, 0x8b, 0x1d, 0x55, 0xe7, 0x5f, 0x39, 0xdb, 0x11, 0x18, 0x3d,
14597
+	0x0c, 0x83, 0x4d, 0x96, 0x07, 0x73, 0xeb, 0xb4, 0xb0, 0xa3, 0x79, 0x19, 0xf6, 0x6c, 0x0d, 0xc0,
14598
+	0x8f, 0x44, 0xe2, 0xfb, 0x6a, 0xe6, 0xf9, 0x27, 0xaa, 0x8b, 0x63, 0x41, 0x3a, 0x4d, 0x25, 0x98,
14599
+	0x6f, 0xcc, 0xeb, 0xe4, 0xc2, 0x8c, 0x6c, 0x2d, 0xe0, 0xa9, 0x1c, 0xfa, 0x18, 0x0a, 0x7c, 0xdc,
14600
+	0x46, 0x20, 0x78, 0x2a, 0xb7, 0xbc, 0xd4, 0x55, 0x52, 0x03, 0x86, 0x51, 0xf4, 0x5d, 0xd3, 0x60,
14601
+	0xd9, 0x1f, 0x7b, 0x7c, 0xd8, 0x4a, 0x87, 0xee, 0xc0, 0x37, 0xdb, 0x84, 0x1d, 0x53, 0xff, 0xb0,
14602
+	0xca, 0x98, 0x69, 0x1d, 0x0c, 0x89, 0xa7, 0x7c, 0x1c, 0x4b, 0xac, 0x13, 0x33, 0x89, 0xf5, 0x1a,
14603
+	0x2c, 0x9a, 0xae, 0x63, 0x06, 0x44, 0x66, 0x23, 0x79, 0x1c, 0x36, 0x79, 0xfa, 0xcf, 0x8b, 0x09,
14604
+	0x12, 0x04, 0x44, 0xd6, 0xf7, 0x79, 0x3c, 0x25, 0xe8, 0xff, 0x98, 0x04, 0x68, 0x75, 0xab, 0x3b,
14605
+	0x4a, 0x7d, 0x03, 0xb2, 0xfb, 0xe6, 0xd0, 0x71, 0x27, 0x57, 0x2d, 0xf0, 0x29, 0xbe, 0x52, 0x95,
14606
+	0x8a, 0x36, 0x85, 0x0c, 0x56, 0xb2, 0xa2, 0x2a, 0x18, 0xef, 0x79, 0x84, 0x45, 0x55, 0x81, 0x68,
14607
+	0xf1, 0x14, 0xc4, 0x37, 0xbd, 0x68, 0x66, 0x64, 0x83, 0x9b, 0x3e, 0x30, 0x19, 0x39, 0x36, 0x27,
14608
+	0xe1, 0xaa, 0x54, 0x4d, 0xb4, 0xc5, 0xab, 0x85, 0x80, 0xf8, 0x47, 0xc4, 0x5e, 0xcb, 0x88, 0x10,
14609
+	0xbc, 0xce, 0x1e, 0xac, 0xe0, 0x32, 0xb9, 0x8a, 0xa4, 0x4b, 0x1f, 0x8a, 0x8c, 0x60, 0xca, 0xfa,
14610
+	0x4a, 0xb7, 0x13, 0xf7, 0x60, 0x69, 0x66, 0x9c, 0x2f, 0x95, 0x63, 0xad, 0xee, 0xd3, 0xef, 0x69,
14611
+	0x69, 0xf5, 0xf5, 0x03, 0x2d, 0xab, 0xff, 0x69, 0x4a, 0xae, 0x23, 0xe5, 0xd5, 0xf9, 0xf7, 0x85,
14612
+	0x39, 0x11, 0xfd, 0x16, 0x75, 0x55, 0x7c, 0xbf, 0x75, 0xf5, 0xf2, 0xe2, 0xe9, 0xbd, 0x80, 0xe3,
14613
+	0x48, 0x10, 0x6d, 0x40, 0x41, 0xce, 0xbf, 0xc1, 0xe3, 0x49, 0xb8, 0x75, 0x09, 0x83, 0x24, 0x71,
14614
+	0x49, 0x74, 0x17, 0x96, 0x45, 0xf9, 0x1e, 0x1c, 0x10, 0x5b, 0x62, 0xd2, 0x02, 0xb3, 0x14, 0x51,
14615
+	0x05, 0x6c, 0x07, 0x8a, 0x8a, 0x60, 0x88, 0xd4, 0x2e, 0x23, 0x0c, 0x7a, 0xe7, 0x3a, 0x83, 0xa4,
14616
+	0x88, 0xc8, 0xf8, 0x0a, 0xa3, 0x69, 0x43, 0x6f, 0x40, 0x2e, 0x34, 0x16, 0xad, 0x41, 0xaa, 0x5f,
14617
+	0xef, 0x6a, 0x0b, 0xa5, 0x95, 0x93, 0xd3, 0x72, 0x21, 0x24, 0xf7, 0xeb, 0x5d, 0xce, 0xd9, 0x6d,
14618
+	0x74, 0xb5, 0xc4, 0x2c, 0x67, 0xb7, 0xd1, 0x2d, 0xa5, 0x79, 0x8a, 0xa1, 0xef, 0x43, 0x21, 0xd6,
14619
+	0x03, 0x7a, 0x03, 0x16, 0x5b, 0xed, 0xc7, 0xb8, 0xd9, 0xeb, 0x69, 0x0b, 0xa5, 0x5b, 0x27, 0xa7,
14620
+	0x65, 0x14, 0xe3, 0xb6, 0xbc, 0x01, 0x9f, 0x1f, 0xf4, 0x1a, 0xa4, 0xb7, 0x3a, 0xfc, 0xe8, 0x92,
14621
+	0xb9, 0x64, 0x0c, 0xb1, 0x45, 0x03, 0x56, 0xba, 0xa9, 0x72, 0x97, 0xb8, 0x62, 0xfd, 0x0f, 0x13,
14622
+	0x90, 0x95, 0x29, 0xf5, 0xdc, 0x89, 0xaa, 0xc2, 0x62, 0x58, 0xe8, 0xc9, 0x3c, 0xff, 0xad, 0xcb,
14623
+	0x73, 0xf2, 0x8a, 0x4a, 0xa1, 0x65, 0xf8, 0x85, 0x72, 0xa5, 0x0f, 0xa0, 0x18, 0x67, 0x7c, 0xa5,
14624
+	0xe0, 0xfb, 0x35, 0x28, 0xf0, 0xf8, 0x0e, 0x73, 0xf3, 0x07, 0x90, 0x95, 0x69, 0x7f, 0xb4, 0x95,
14625
+	0x5e, 0x5e, 0x20, 0x28, 0x24, 0x7a, 0x04, 0x8b, 0xb2, 0xa8, 0x08, 0xef, 0xf7, 0xd6, 0xaf, 0x5e,
14626
+	0x45, 0x38, 0x84, 0xeb, 0x1f, 0x43, 0xba, 0x4b, 0x88, 0xcf, 0x7d, 0xef, 0x51, 0x9b, 0x4c, 0x4f,
14627
+	0x1f, 0x55, 0x0f, 0xd9, 0xa4, 0xd5, 0xe0, 0xf5, 0x90, 0x4d, 0x5a, 0x76, 0x74, 0x83, 0x91, 0x8c,
14628
+	0xdd, 0x60, 0xf4, 0xa1, 0xf8, 0x8c, 0x38, 0x83, 0x03, 0x46, 0x6c, 0xa1, 0xe8, 0x5d, 0x48, 0x8f,
14629
+	0x48, 0x64, 0xfc, 0xda, 0xdc, 0x00, 0x23, 0xc4, 0xc7, 0x02, 0xc5, 0xf7, 0x91, 0x63, 0x21, 0xad,
14630
+	0x6e, 0x95, 0x55, 0x4b, 0xff, 0x87, 0x24, 0x2c, 0xb7, 0x82, 0x60, 0x6c, 0x7a, 0x56, 0x98, 0x98,
14631
+	0x7c, 0x34, 0x9b, 0x98, 0xbc, 0x3d, 0x77, 0x84, 0x33, 0x22, 0xb3, 0x17, 0x33, 0xea, 0x70, 0x48,
14632
+	0x46, 0x87, 0x83, 0xfe, 0x1f, 0x89, 0xf0, 0xf6, 0xe5, 0x6e, 0x6c, 0xb9, 0x97, 0xd6, 0x4e, 0x4e,
14633
+	0xcb, 0xab, 0x71, 0x4d, 0x64, 0xd7, 0x3b, 0xf4, 0xe8, 0xb1, 0x87, 0x5e, 0x87, 0x0c, 0x6e, 0xb6,
14634
+	0x9b, 0xcf, 0xb4, 0x84, 0x0c, 0xcf, 0x19, 0x10, 0x26, 0x1e, 0x39, 0xe6, 0x9a, 0xba, 0xcd, 0x76,
14635
+	0x83, 0x27, 0x12, 0xc9, 0x39, 0x9a, 0xba, 0xc4, 0xb3, 0x1d, 0x6f, 0x80, 0xde, 0x80, 0x6c, 0xab,
14636
+	0xd7, 0xdb, 0x15, 0xf5, 0xf1, 0x37, 0x4f, 0x4e, 0xcb, 0x37, 0x67, 0x50, 0xe2, 0xe6, 0xcd, 0xe6,
14637
+	0x20, 0x9e, 0xc5, 0xf3, 0x14, 0x63, 0x0e, 0x88, 0xa7, 0x87, 0x12, 0x84, 0x3b, 0x7d, 0x5e, 0xbc,
14638
+	0x67, 0xe6, 0x80, 0x30, 0xe5, 0x7f, 0xd5, 0x72, 0xfb, 0x97, 0x24, 0x68, 0x55, 0xcb, 0x22, 0x23,
14639
+	0xc6, 0xf9, 0xaa, 0x70, 0xea, 0x43, 0x6e, 0xc4, 0xbf, 0x1c, 0x12, 0x26, 0x01, 0x8f, 0xe6, 0xbe,
14640
+	0x6b, 0x5c, 0x90, 0xab, 0x60, 0xea, 0x92, 0xaa, 0x3d, 0x74, 0x82, 0xc0, 0xa1, 0x9e, 0xa4, 0xe1,
14641
+	0x48, 0x53, 0xe9, 0xbf, 0x12, 0x70, 0x73, 0x0e, 0x02, 0xdd, 0x83, 0xb4, 0x4f, 0xdd, 0x70, 0x0e,
14642
+	0xef, 0x5c, 0x76, 0xb1, 0xc6, 0x45, 0xb1, 0x40, 0xa2, 0x75, 0x00, 0x73, 0xcc, 0xa8, 0x29, 0xfa,
14643
+	0x17, 0xb3, 0x97, 0xc3, 0x31, 0x0a, 0x7a, 0x06, 0xd9, 0x80, 0x58, 0x3e, 0x09, 0x53, 0xc5, 0x8f,
14644
+	0xff, 0xbf, 0xd6, 0x57, 0x7a, 0x42, 0x0d, 0x56, 0xea, 0x4a, 0x15, 0xc8, 0x4a, 0x0a, 0x0f, 0x7b,
14645
+	0xdb, 0x64, 0xa6, 0xba, 0x76, 0x15, 0xdf, 0x3c, 0x9a, 0x4c, 0x77, 0x10, 0x46, 0x93, 0xe9, 0x0e,
14646
+	0xf4, 0xbf, 0x4d, 0x02, 0x34, 0x9f, 0x33, 0xe2, 0x7b, 0xa6, 0x5b, 0xaf, 0xa2, 0x66, 0x6c, 0xf7,
14647
+	0x97, 0xa3, 0xfd, 0xce, 0xdc, 0xbb, 0xe4, 0x48, 0xa2, 0x52, 0xaf, 0xce, 0xd9, 0xff, 0x6f, 0x43,
14648
+	0x6a, 0xec, 0xab, 0xa7, 0x2a, 0x99, 0xe6, 0xed, 0xe2, 0x6d, 0xcc, 0x69, 0xa8, 0x39, 0xdd, 0xb6,
14649
+	0x52, 0x97, 0x3f, 0x48, 0xc5, 0x3a, 0x98, 0xbb, 0x75, 0xf1, 0x95, 0x6f, 0x99, 0x86, 0x45, 0xd4,
14650
+	0xc9, 0x51, 0x94, 0x2b, 0xbf, 0x5e, 0xad, 0x13, 0x9f, 0xe1, 0xac, 0x65, 0xf2, 0xff, 0x5f, 0x6b,
14651
+	0x7f, 0x7b, 0x17, 0x60, 0x3a, 0x34, 0xb4, 0x0e, 0x99, 0xfa, 0x66, 0xaf, 0xb7, 0xad, 0x2d, 0xc8,
14652
+	0x0d, 0x7c, 0xca, 0x12, 0x64, 0xfd, 0x2f, 0x93, 0x90, 0xab, 0x57, 0xd5, 0xb1, 0x5a, 0x07, 0x4d,
14653
+	0xec, 0x4a, 0xe2, 0xb2, 0x9a, 0x3c, 0x1f, 0x39, 0xfe, 0x44, 0x6d, 0x2c, 0x57, 0xd4, 0x6c, 0xcb,
14654
+	0x5c, 0x84, 0x5b, 0xdd, 0x14, 0x02, 0x08, 0x43, 0x91, 0x28, 0x27, 0x18, 0x96, 0x19, 0xee, 0xf1,
14655
+	0xeb, 0x57, 0x3b, 0x4b, 0x66, 0xdf, 0xd3, 0x76, 0x80, 0x0b, 0xa1, 0x92, 0xba, 0x19, 0xa0, 0xf7,
14656
+	0x61, 0x25, 0x70, 0x06, 0x9e, 0xe3, 0x0d, 0x8c, 0xd0, 0x79, 0xe2, 0xe6, 0xbc, 0x76, 0xe3, 0xfc,
14657
+	0x6c, 0x63, 0xa9, 0x27, 0x59, 0xca, 0x87, 0x4b, 0x0a, 0x59, 0x17, 0xae, 0x44, 0x3f, 0x80, 0xe5,
14658
+	0x98, 0x28, 0xf7, 0xa2, 0x74, 0xbb, 0x76, 0x7e, 0xb6, 0x51, 0x8c, 0x24, 0x9f, 0x90, 0x09, 0x2e,
14659
+	0x46, 0x82, 0x4f, 0x88, 0xb8, 0x5e, 0xd8, 0xa7, 0xbe, 0x45, 0x0c, 0x5f, 0xac, 0x69, 0x71, 0x82,
14660
+	0xa7, 0x71, 0x41, 0xd0, 0xe4, 0x32, 0xd7, 0x9f, 0xc2, 0xcd, 0x8e, 0x6f, 0x1d, 0x90, 0x80, 0x49,
14661
+	0x57, 0x28, 0x2f, 0x7e, 0x0c, 0x77, 0x98, 0x19, 0x1c, 0x1a, 0x07, 0x4e, 0xc0, 0xa8, 0x3f, 0x31,
14662
+	0x7c, 0xc2, 0x88, 0xc7, 0xf9, 0x86, 0x78, 0x6e, 0x53, 0xf7, 0x3f, 0xb7, 0x39, 0x66, 0x4b, 0x42,
14663
+	0x70, 0x88, 0xd8, 0xe6, 0x00, 0xbd, 0x05, 0x45, 0x9e, 0x85, 0x37, 0xc8, 0xbe, 0x39, 0x76, 0x19,
14664
+	0x1f, 0x3d, 0xb8, 0x74, 0x60, 0xbc, 0xf2, 0x31, 0x95, 0x77, 0xe9, 0x40, 0x7e, 0xea, 0x3f, 0x06,
14665
+	0xad, 0xe1, 0x04, 0x23, 0x93, 0x59, 0x07, 0xe1, 0xc5, 0x16, 0x6a, 0x80, 0x76, 0x40, 0x4c, 0x9f,
14666
+	0xed, 0x11, 0x93, 0x19, 0x23, 0xe2, 0x3b, 0xd4, 0xbe, 0x7e, 0x96, 0x57, 0x22, 0x91, 0xae, 0x90,
14667
+	0xd0, 0xff, 0x3b, 0x01, 0x80, 0xcd, 0xfd, 0x30, 0x23, 0xfb, 0x2e, 0xdc, 0x08, 0x3c, 0x73, 0x14,
14668
+	0x1c, 0x50, 0x66, 0x38, 0x1e, 0x23, 0xfe, 0x91, 0xe9, 0xaa, 0xfb, 0x09, 0x2d, 0x64, 0xb4, 0x14,
14669
+	0x1d, 0xbd, 0x0b, 0xe8, 0x90, 0x90, 0x91, 0x41, 0x5d, 0xdb, 0x08, 0x99, 0xf2, 0x31, 0x30, 0x8d,
14670
+	0x35, 0xce, 0xe9, 0xb8, 0x76, 0x2f, 0xa4, 0xa3, 0x1a, 0xac, 0xf3, 0xe1, 0x13, 0x8f, 0xf9, 0x0e,
14671
+	0x09, 0x8c, 0x7d, 0xea, 0x1b, 0x81, 0x4b, 0x8f, 0x8d, 0x7d, 0xea, 0xba, 0xf4, 0x98, 0xf8, 0xe1,
14672
+	0xd5, 0x4f, 0xc9, 0xa5, 0x83, 0xa6, 0x04, 0x6d, 0x52, 0xbf, 0xe7, 0xd2, 0xe3, 0xcd, 0x10, 0xc1,
14673
+	0xd3, 0xb6, 0xe9, 0x98, 0x99, 0x63, 0x1d, 0x86, 0x69, 0x5b, 0x44, 0xed, 0x3b, 0xd6, 0x21, 0x7a,
14674
+	0x03, 0x96, 0x88, 0x4b, 0xc4, 0x0d, 0x80, 0x44, 0x65, 0x04, 0xaa, 0x18, 0x12, 0x39, 0x48, 0xff,
14675
+	0x04, 0xb4, 0xa6, 0x67, 0xf9, 0x93, 0x51, 0x6c, 0xce, 0xdf, 0x05, 0xc4, 0x37, 0x49, 0xc3, 0xa5,
14676
+	0xd6, 0xa1, 0x31, 0x34, 0x3d, 0x73, 0xc0, 0xed, 0x92, 0x6f, 0x34, 0x1a, 0xe7, 0x6c, 0x53, 0xeb,
14677
+	0x70, 0x47, 0xd1, 0xf5, 0xf7, 0x01, 0x7a, 0x23, 0x9f, 0x98, 0x76, 0x87, 0x67, 0x13, 0xdc, 0x75,
14678
+	0xa2, 0x65, 0xd8, 0xea, 0x8d, 0x8b, 0xfa, 0x6a, 0xa9, 0x6b, 0x92, 0xd1, 0x88, 0xe8, 0xfa, 0x2f,
14679
+	0xc1, 0xcd, 0xae, 0x6b, 0x5a, 0xe2, 0xbd, 0xb7, 0x1b, 0x3d, 0x3a, 0xa0, 0x47, 0x90, 0x95, 0x50,
14680
+	0x35, 0x93, 0x73, 0x97, 0xdb, 0xb4, 0xcf, 0xad, 0x05, 0xac, 0xf0, 0xb5, 0x22, 0xc0, 0x54, 0x8f,
14681
+	0xfe, 0x1c, 0xf2, 0x91, 0x7a, 0x54, 0x06, 0x5e, 0x02, 0xf3, 0xe8, 0x76, 0x3c, 0x55, 0xb3, 0xe6,
14682
+	0x71, 0x9c, 0x84, 0x5a, 0x50, 0x18, 0x45, 0xc2, 0x57, 0xa6, 0x73, 0x73, 0x8c, 0xc6, 0x71, 0x59,
14683
+	0xfd, 0x23, 0x80, 0x1f, 0x51, 0xc7, 0xeb, 0xd3, 0x43, 0xe2, 0x89, 0x77, 0x2e, 0x5e, 0xad, 0x91,
14684
+	0xd0, 0x11, 0xaa, 0x25, 0x8a, 0x51, 0xe9, 0xc5, 0xe8, 0xb9, 0x47, 0x36, 0xf5, 0xbf, 0x49, 0x42,
14685
+	0x16, 0x53, 0xca, 0xea, 0x55, 0x54, 0x86, 0xac, 0x5a, 0xea, 0xe2, 0x08, 0xa9, 0xe5, 0xcf, 0xcf,
14686
+	0x36, 0x32, 0x72, 0x8d, 0x67, 0x2c, 0xb1, 0xb8, 0x63, 0x9b, 0x70, 0xf2, 0xb2, 0x4d, 0x18, 0xdd,
14687
+	0x83, 0xa2, 0x02, 0x19, 0x07, 0x66, 0x70, 0x20, 0x6b, 0xac, 0xda, 0xf2, 0xf9, 0xd9, 0x06, 0x48,
14688
+	0xe4, 0x96, 0x19, 0x1c, 0x60, 0x90, 0x68, 0xfe, 0x8d, 0x9a, 0x50, 0xf8, 0x8c, 0x3a, 0x9e, 0xc1,
14689
+	0xc4, 0x20, 0xd4, 0x75, 0xd7, 0xdc, 0xa9, 0x98, 0x0e, 0x55, 0x3d, 0xfa, 0xc2, 0x67, 0xd3, 0xc1,
14690
+	0x37, 0x61, 0xc9, 0xa7, 0x94, 0xc9, 0x9d, 0xc7, 0xa1, 0x9e, 0xaa, 0xa4, 0xcb, 0x73, 0x2f, 0x58,
14691
+	0x29, 0x65, 0x58, 0xe1, 0x70, 0xd1, 0x8f, 0xb5, 0xd0, 0x3d, 0x58, 0x75, 0xcd, 0x80, 0x19, 0x62,
14692
+	0xcb, 0xb2, 0xa7, 0xda, 0xb2, 0x62, 0xb5, 0x20, 0xce, 0xdb, 0x14, 0xac, 0x50, 0x42, 0xff, 0xa7,
14693
+	0x04, 0x14, 0xf8, 0x60, 0x9c, 0x7d, 0xc7, 0xe2, 0x79, 0xda, 0x57, 0x4f, 0x1f, 0x6e, 0x43, 0xca,
14694
+	0x0a, 0x7c, 0xe5, 0x54, 0x71, 0x7e, 0xd6, 0x7b, 0x18, 0x73, 0x1a, 0xfa, 0x04, 0xb2, 0xaa, 0xa2,
14695
+	0x97, 0x99, 0x83, 0x7e, 0x7d, 0x46, 0xa9, 0x7c, 0xa3, 0xe4, 0x44, 0x3c, 0x4e, 0xad, 0x93, 0xfb,
14696
+	0x38, 0x8e, 0x93, 0xd0, 0x2d, 0x48, 0x5a, 0xd2, 0x5d, 0xea, 0x57, 0x05, 0xf5, 0x36, 0x4e, 0x5a,
14697
+	0x9e, 0xfe, 0xf7, 0x09, 0x58, 0x9a, 0xae, 0x59, 0x1e, 0x01, 0x77, 0x20, 0x1f, 0x8c, 0xf7, 0x82,
14698
+	0x49, 0xc0, 0xc8, 0x30, 0x7c, 0xc3, 0x8b, 0x08, 0xa8, 0x05, 0x79, 0xd3, 0x1d, 0x50, 0xdf, 0x61,
14699
+	0x07, 0x43, 0x55, 0x4c, 0xce, 0x3f, 0xed, 0xe3, 0x3a, 0x2b, 0xd5, 0x50, 0x04, 0x4f, 0xa5, 0xc3,
14700
+	0xa3, 0x5b, 0x3e, 0xf4, 0x8a, 0xa3, 0xfb, 0x75, 0x28, 0xba, 0xe6, 0x50, 0x5c, 0x71, 0x30, 0x67,
14701
+	0x28, 0xc7, 0x91, 0xc6, 0x05, 0x45, 0xeb, 0x3b, 0x43, 0xa2, 0xeb, 0x90, 0x8f, 0x94, 0xa1, 0x15,
14702
+	0x28, 0x54, 0x9b, 0x3d, 0xe3, 0xfe, 0x83, 0x47, 0xc6, 0xe3, 0xfa, 0x8e, 0xb6, 0xa0, 0xd2, 0xcb,
14703
+	0xbf, 0x48, 0xc0, 0x92, 0xda, 0x51, 0x54, 0xca, 0xfe, 0x06, 0x2c, 0xfa, 0xe6, 0x3e, 0x0b, 0x8b,
14704
+	0x8a, 0xb4, 0x8c, 0x6a, 0xbe, 0x49, 0xf3, 0xa2, 0x82, 0xb3, 0xe6, 0x17, 0x15, 0xb1, 0x57, 0xe5,
14705
+	0xd4, 0x95, 0xaf, 0xca, 0xe9, 0x9f, 0xcb, 0xab, 0xb2, 0xfe, 0x9b, 0x00, 0x9b, 0x8e, 0x4b, 0xfa,
14706
+	0xf2, 0xa2, 0x65, 0x5e, 0x89, 0xc8, 0xd3, 0x30, 0x75, 0xdb, 0x16, 0xa6, 0x61, 0xad, 0x06, 0xe6,
14707
+	0x34, 0xce, 0x1a, 0x38, 0xb6, 0x5a, 0x8c, 0x82, 0xf5, 0x98, 0xb3, 0x06, 0x8e, 0x1d, 0xbd, 0xa3,
14708
+	0xa4, 0xaf, 0x7b, 0x47, 0x39, 0x4d, 0xc0, 0x8a, 0x4a, 0x3f, 0xa3, 0x1d, 0xf4, 0x3b, 0x90, 0x97,
14709
+	0x99, 0xe8, 0xb4, 0x26, 0x13, 0x2f, 0xa9, 0x12, 0xd7, 0x6a, 0xe0, 0x9c, 0x64, 0xb7, 0x6c, 0xb4,
14710
+	0x01, 0x05, 0x05, 0x8d, 0xfd, 0x02, 0x05, 0x24, 0xa9, 0xcd, 0xcd, 0xff, 0x1e, 0xa4, 0xf7, 0x1d,
14711
+	0x97, 0xa8, 0x40, 0x9f, 0xbb, 0x01, 0x4c, 0x1d, 0xb0, 0xb5, 0x80, 0x05, 0xba, 0x96, 0x0b, 0x6f,
14712
+	0xa2, 0x84, 0x7d, 0xaa, 0x72, 0x8c, 0xdb, 0x27, 0x8b, 0xc8, 0x0b, 0xf6, 0x49, 0x1c, 0xb7, 0x4f,
14713
+	0xb2, 0xa5, 0x7d, 0x0a, 0x1a, 0xb7, 0x4f, 0x92, 0x7e, 0x2e, 0xf6, 0x6d, 0xc3, 0xad, 0x9a, 0x6b,
14714
+	0x5a, 0x87, 0xae, 0x13, 0x30, 0x62, 0xc7, 0x77, 0x8c, 0x07, 0x90, 0x9d, 0xc9, 0x1b, 0xaf, 0xba,
14715
+	0x98, 0x54, 0x48, 0xfd, 0xdf, 0x13, 0x50, 0xdc, 0x22, 0xa6, 0xcb, 0x0e, 0xa6, 0xb7, 0x3b, 0x8c,
14716
+	0x04, 0x4c, 0x1d, 0x38, 0xe2, 0x1b, 0x7d, 0x1f, 0x72, 0x51, 0x5a, 0x71, 0xed, 0x0b, 0x51, 0x04,
14717
+	0x45, 0x0f, 0x61, 0x91, 0xaf, 0x31, 0x3a, 0x0e, 0xeb, 0x95, 0xab, 0x1e, 0x1f, 0x14, 0x92, 0x1f,
14718
+	0x32, 0x3e, 0x11, 0x79, 0x84, 0x08, 0xa5, 0x0c, 0x0e, 0x9b, 0xe8, 0x17, 0xa1, 0x28, 0xee, 0xce,
14719
+	0xc3, 0xb4, 0x29, 0x73, 0x9d, 0xce, 0x82, 0x7c, 0xfe, 0x92, 0x29, 0xd3, 0xff, 0x26, 0x60, 0x75,
14720
+	0xc7, 0x9c, 0xec, 0x11, 0xb5, 0x6d, 0x10, 0x1b, 0x13, 0x8b, 0xfa, 0x36, 0xea, 0xc6, 0xb7, 0x9b,
14721
+	0x2b, 0x5e, 0xd3, 0xe6, 0x09, 0xcf, 0xdf, 0x75, 0xc2, 0x1a, 0x2a, 0x19, 0xab, 0xa1, 0x56, 0x21,
14722
+	0xe3, 0x51, 0xcf, 0x22, 0x6a, 0x2f, 0x92, 0x0d, 0xdd, 0x89, 0x6f, 0x35, 0xa5, 0xe8, 0xa1, 0x4b,
14723
+	0x3c, 0x53, 0xb5, 0x29, 0x8b, 0x7a, 0x43, 0x9f, 0x40, 0xa9, 0xd7, 0xac, 0xe3, 0x66, 0xbf, 0xd6,
14724
+	0xf9, 0xb1, 0xd1, 0xab, 0x6e, 0xf7, 0xaa, 0x0f, 0xee, 0x19, 0xdd, 0xce, 0xf6, 0xa7, 0xf7, 0x1f,
14725
+	0xde, 0xfb, 0xbe, 0x96, 0x28, 0x95, 0x4f, 0x4e, 0xcb, 0x77, 0xda, 0xd5, 0xfa, 0xb6, 0x5c, 0x31,
14726
+	0x7b, 0xf4, 0x79, 0xcf, 0x74, 0x03, 0xf3, 0xc1, 0xbd, 0x2e, 0x75, 0x27, 0x1c, 0xc3, 0xc3, 0xba,
14727
+	0x18, 0x3f, 0xaf, 0xe2, 0xc7, 0x70, 0xe2, 0xd2, 0x63, 0x78, 0x7a, 0x9a, 0x27, 0x2f, 0x39, 0xcd,
14728
+	0x37, 0x61, 0xd5, 0xf2, 0x69, 0x10, 0x18, 0x3c, 0x81, 0x27, 0xf6, 0x85, 0x12, 0xe1, 0x1b, 0xe7,
14729
+	0x67, 0x1b, 0x37, 0xea, 0x9c, 0xdf, 0x13, 0x6c, 0xa5, 0xfe, 0x86, 0x15, 0x23, 0x89, 0x9e, 0xf4,
14730
+	0x3f, 0x4a, 0xf1, 0x5c, 0xc8, 0x39, 0x72, 0x5c, 0x32, 0x20, 0x01, 0x7a, 0x0a, 0x2b, 0x96, 0x4f,
14731
+	0x6c, 0x9e, 0x99, 0x9b, 0xae, 0x11, 0x8c, 0x88, 0xa5, 0x82, 0xfa, 0x17, 0xe6, 0x26, 0x38, 0x91,
14732
+	0x60, 0xa5, 0x1e, 0x49, 0xf5, 0x46, 0xc4, 0xc2, 0xcb, 0xd6, 0x4c, 0x1b, 0x7d, 0x06, 0x2b, 0x01,
14733
+	0x71, 0x1d, 0x6f, 0xfc, 0xdc, 0xb0, 0xa8, 0xc7, 0xc8, 0xf3, 0xf0, 0xcd, 0xe6, 0x3a, 0xbd, 0xbd,
14734
+	0xe6, 0x36, 0x97, 0xaa, 0x4b, 0xa1, 0x1a, 0x3a, 0x3f, 0xdb, 0x58, 0x9e, 0xa5, 0xe1, 0x65, 0xa5,
14735
+	0x59, 0xb5, 0x4b, 0x6d, 0x58, 0x9e, 0xb5, 0x06, 0xad, 0xaa, 0xb5, 0x2f, 0xb6, 0x90, 0x70, 0x6d,
14736
+	0xa3, 0x3b, 0x90, 0xf3, 0xc9, 0xc0, 0x09, 0x98, 0x2f, 0xdd, 0xcc, 0x39, 0x11, 0x85, 0xaf, 0x7c,
14737
+	0xf9, 0x33, 0x94, 0xd2, 0xaf, 0xc3, 0x85, 0x1e, 0xf9, 0x62, 0xb1, 0x9d, 0xc0, 0xdc, 0x53, 0x2a,
14738
+	0x73, 0x38, 0x6c, 0xf2, 0x18, 0x1c, 0x07, 0x51, 0xa2, 0x26, 0xbe, 0x39, 0x4d, 0x64, 0x14, 0xea,
14739
+	0x47, 0x39, 0x22, 0x67, 0x08, 0x7f, 0xdd, 0x97, 0x8e, 0xfd, 0xba, 0x6f, 0x15, 0x32, 0x2e, 0x39,
14740
+	0x22, 0xae, 0x3c, 0xcb, 0xb1, 0x6c, 0xbc, 0xf3, 0xb3, 0x14, 0xe4, 0xa3, 0xf7, 0x09, 0x7e, 0x12,
14741
+	0xb4, 0x9b, 0xcf, 0xc2, 0x58, 0x8d, 0xe8, 0x6d, 0x72, 0x8c, 0x5e, 0x9f, 0x5e, 0x0b, 0x7d, 0x22,
14742
+	0x1f, 0x64, 0x23, 0x76, 0x78, 0x25, 0xf4, 0x26, 0xe4, 0xaa, 0xbd, 0x5e, 0xeb, 0x71, 0xbb, 0xd9,
14743
+	0xd0, 0x3e, 0x4f, 0x94, 0xbe, 0x71, 0x72, 0x5a, 0xbe, 0x11, 0x81, 0xaa, 0x81, 0x0c, 0x25, 0x81,
14744
+	0xaa, 0xd7, 0x9b, 0xdd, 0x7e, 0xb3, 0xa1, 0xbd, 0x48, 0x5e, 0x44, 0x89, 0x6b, 0x0e, 0xf1, 0xb3,
14745
+	0x8a, 0x7c, 0x17, 0x37, 0xbb, 0x55, 0xcc, 0x3b, 0xfc, 0x3c, 0x29, 0x6f, 0xab, 0xa6, 0x3d, 0xfa,
14746
+	0x64, 0x64, 0xfa, 0xbc, 0xcf, 0xf5, 0xf0, 0xe7, 0x45, 0x2f, 0x52, 0xf2, 0xe9, 0x7d, 0xfa, 0xd8,
14747
+	0x42, 0x4c, 0x7b, 0xc2, 0x7b, 0x13, 0xaf, 0x5c, 0x42, 0x4d, 0xea, 0x42, 0x6f, 0x3d, 0xbe, 0x93,
14748
+	0x70, 0x2d, 0x3a, 0x2c, 0xe2, 0xdd, 0x76, 0x9b, 0x83, 0x5e, 0xa4, 0x2f, 0x8c, 0x0e, 0x8f, 0x3d,
14749
+	0x5e, 0xc2, 0xa2, 0xbb, 0x90, 0x0b, 0x1f, 0xc1, 0xb4, 0xcf, 0xd3, 0x17, 0x0c, 0xaa, 0x87, 0x2f,
14750
+	0x78, 0xa2, 0xc3, 0xad, 0xdd, 0xbe, 0xf8, 0xf5, 0xd3, 0x8b, 0xcc, 0xc5, 0x0e, 0x0f, 0xc6, 0xcc,
14751
+	0xa6, 0xc7, 0x1e, 0x5f, 0x81, 0xea, 0x62, 0xec, 0xf3, 0x8c, 0xbc, 0x45, 0x88, 0x30, 0xea, 0x56,
14752
+	0xec, 0x4d, 0xc8, 0xe1, 0xe6, 0x8f, 0xe4, 0x0f, 0xa5, 0x5e, 0x64, 0x2f, 0xe8, 0xc1, 0xe4, 0x33,
14753
+	0x62, 0xa9, 0xde, 0x3a, 0xb8, 0xbb, 0x55, 0x15, 0x2e, 0xbf, 0x88, 0xea, 0xf8, 0xa3, 0x03, 0xd3,
14754
+	0x23, 0xf6, 0xf4, 0xf7, 0x07, 0x11, 0xeb, 0x9d, 0x5f, 0x86, 0x5c, 0x98, 0x67, 0xa2, 0x75, 0xc8,
14755
+	0x3e, 0xeb, 0xe0, 0x27, 0x4d, 0xac, 0x2d, 0x48, 0x1f, 0x86, 0x9c, 0x67, 0xb2, 0x42, 0x28, 0xc3,
14756
+	0xe2, 0x4e, 0xb5, 0x5d, 0x7d, 0xdc, 0xc4, 0xe1, 0x9d, 0x75, 0x08, 0x50, 0xc9, 0x52, 0x49, 0x53,
14757
+	0x1d, 0x44, 0x3a, 0x6b, 0x6b, 0x5f, 0x7c, 0xb9, 0xbe, 0xf0, 0xd3, 0x2f, 0xd7, 0x17, 0x5e, 0x9c,
14758
+	0xaf, 0x27, 0xbe, 0x38, 0x5f, 0x4f, 0xfc, 0xe4, 0x7c, 0x3d, 0xf1, 0x6f, 0xe7, 0xeb, 0x89, 0xbd,
14759
+	0xac, 0xd8, 0xd2, 0x1f, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xf3, 0xe4, 0x8f, 0x7c,
14760
+	0x2d, 0x00, 0x00,
14741 14761
 }
... ...
@@ -86,6 +86,18 @@ message NodeDescription {
86 86
 
87 87
 	// Information about the Docker Engine on the node.
88 88
 	EngineDescription engine = 4;
89
+
90
+	// Information on the node's TLS setup
91
+	NodeTLSInfo tls_info = 5 [(gogoproto.customname) = "TLSInfo"];
92
+}
93
+
94
+message NodeTLSInfo {
95
+	// Information about which root certs the node trusts
96
+	bytes trust_root = 1;
97
+
98
+	// Information about the node's current TLS certificate
99
+	bytes cert_issuer_subject = 2;
100
+	bytes cert_issuer_public_key = 3;
89 101
 }
90 102
 
91 103
 message RaftMemberStatus {
... ...
@@ -853,6 +865,20 @@ message ManagerStatus {
853 853
 	RaftMemberStatus.Reachability reachability = 4;
854 854
 }
855 855
 
856
+// FileTarget represents a specific target that is backed by a file
857
+message FileTarget {
858
+	// Name represents the final filename in the filesystem
859
+	string name = 1;
860
+
861
+	// UID represents the file UID
862
+	string uid = 2 [(gogoproto.customname) = "UID"];
863
+
864
+	// GID represents the file GID
865
+	string gid = 3 [(gogoproto.customname) = "GID"];
866
+
867
+	// Mode represents the FileMode of the file
868
+	uint32 mode = 4 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false];
869
+}
856 870
 
857 871
 // SecretReference is the linkage between a service and a secret that it uses.
858 872
 message SecretReference {
... ...
@@ -865,20 +891,21 @@ message SecretReference {
865 865
 	// lookup/display purposes.  The secret in the reference will be identified by its ID.
866 866
 	string secret_name = 2;
867 867
 
868
-	// FileTarget represents a specific target that is backed by a file
869
-	message FileTarget {
870
-		// Name represents the final filename in the filesystem
871
-		string name = 1;
872
-
873
-		// UID represents the file UID
874
-		string uid = 2 [(gogoproto.customname) = "UID"];
868
+	// Target specifies how this secret should be exposed to the task.
869
+	oneof target {
870
+		FileTarget file = 3;
871
+	}
872
+}
875 873
 
876
-		// GID represents the file GID
877
-		string gid = 3 [(gogoproto.customname) = "GID"];
874
+// ConfigReference is the linkage between a service and a config that it uses.
875
+message ConfigReference {
876
+	// ConfigID represents the ID of the specific Config that we're
877
+	// referencing.
878
+	string config_id = 1;
878 879
 
879
-		// Mode represents the FileMode of the file
880
-		uint32 mode = 4 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false];
881
-	}
880
+	// ConfigName is the name of the config that this references, but this is just provided for
881
+	// lookup/display purposes. The config in the reference will be identified by its ID.
882
+	string config_name = 2;
882 883
 
883 884
 	// Target specifies how this secret should be exposed to the task.
884 885
 	oneof target {
... ...
@@ -943,3 +970,26 @@ message RootRotation {
943 943
 	// cross-signed CA cert is the CACert that has been cross-signed by the previous root
944 944
 	bytes cross_signed_ca_cert = 3 [(gogoproto.customname) = "CrossSignedCACert"];
945 945
 }
946
+
947
+// Privileges specifies security configuration/permissions.
948
+message Privileges {
949
+	// CredentialSpec for managed service account (Windows only).
950
+	message CredentialSpec {
951
+		oneof source {
952
+			string file = 1;
953
+			string registry = 2;
954
+		}
955
+	}
956
+	CredentialSpec credential_spec = 1;
957
+
958
+	// SELinuxContext contains the SELinux labels for the container.
959
+	message SELinuxContext {
960
+		bool disable = 1;
961
+
962
+		string user = 2;
963
+		string role = 3;
964
+		string type = 4;
965
+		string level = 5;
966
+	}
967
+	SELinuxContext selinux_context = 2 [(gogoproto.customname) = "SELinuxContext"];
968
+}
... ...
@@ -104,6 +104,12 @@ type CertPaths struct {
104 104
 	Cert, Key string
105 105
 }
106 106
 
107
+// IssuerInfo contains the subject and public key of the issuer of a certificate
108
+type IssuerInfo struct {
109
+	Subject   []byte
110
+	PublicKey []byte
111
+}
112
+
107 113
 // LocalSigner is a signer that can sign CSRs
108 114
 type LocalSigner struct {
109 115
 	cfsigner.Signer
... ...
@@ -192,39 +198,47 @@ func (rca *RootCA) Signer() (*LocalSigner, error) {
192 192
 }
193 193
 
194 194
 // IssueAndSaveNewCertificates generates a new key-pair, signs it with the local root-ca, and returns a
195
-// tls certificate
196
-func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, error) {
195
+// TLS certificate and the issuer information for the certificate.
196
+func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, *IssuerInfo, error) {
197 197
 	csr, key, err := GenerateNewCSR()
198 198
 	if err != nil {
199
-		return nil, errors.Wrap(err, "error when generating new node certs")
199
+		return nil, nil, errors.Wrap(err, "error when generating new node certs")
200 200
 	}
201 201
 
202 202
 	// Obtain a signed Certificate
203 203
 	certChain, err := rca.ParseValidateAndSignCSR(csr, cn, ou, org)
204 204
 	if err != nil {
205
-		return nil, errors.Wrap(err, "failed to sign node certificate")
205
+		return nil, nil, errors.Wrap(err, "failed to sign node certificate")
206
+	}
207
+	signer, err := rca.Signer()
208
+	if err != nil { // should never happen, since if ParseValidateAndSignCSR did not fail this root CA must have a signer
209
+		return nil, nil, err
206 210
 	}
207 211
 
208 212
 	// Create a valid TLSKeyPair out of the PEM encoded private key and certificate
209 213
 	tlsKeyPair, err := tls.X509KeyPair(certChain, key)
210 214
 	if err != nil {
211
-		return nil, err
215
+		return nil, nil, err
212 216
 	}
213 217
 
214
-	if err := kw.Write(certChain, key, nil); err != nil {
215
-		return nil, err
218
+	if err := kw.Write(NormalizePEMs(certChain), key, nil); err != nil {
219
+		return nil, nil, err
216 220
 	}
217 221
 
218
-	return &tlsKeyPair, nil
222
+	return &tlsKeyPair, &IssuerInfo{
223
+		PublicKey: signer.parsedCert.RawSubjectPublicKeyInfo,
224
+		Subject:   signer.parsedCert.RawSubject,
225
+	}, nil
219 226
 }
220 227
 
221 228
 // RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is
222
-// available, or by requesting them from the remote server at remoteAddr.
223
-func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, error) {
229
+// available, or by requesting them from the remote server at remoteAddr.  This function returns the TLS
230
+// certificate and the issuer information for the certificate.
231
+func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, *IssuerInfo, error) {
224 232
 	// Create a new key/pair and CSR
225 233
 	csr, key, err := GenerateNewCSR()
226 234
 	if err != nil {
227
-		return nil, errors.Wrap(err, "error when generating new node certs")
235
+		return nil, nil, errors.Wrap(err, "error when generating new node certs")
228 236
 	}
229 237
 
230 238
 	// Get the remote manager to issue a CA signed certificate for this node
... ...
@@ -246,41 +260,49 @@ func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWrit
246 246
 		config.ForceRemote = true
247 247
 	}
248 248
 	if err != nil {
249
-		return nil, err
249
+		return nil, nil, err
250 250
 	}
251 251
 
252 252
 	// Доверяй, но проверяй.
253 253
 	// Before we overwrite our local key + certificate, let's make sure the server gave us one that is valid
254 254
 	// Create an X509Cert so we can .Verify()
255 255
 	// Check to see if this certificate was signed by our CA, and isn't expired
256
-	parsedCerts, err := ValidateCertChain(rca.Pool, signedCert, false)
256
+	parsedCerts, chains, err := ValidateCertChain(rca.Pool, signedCert, false)
257 257
 	if err != nil {
258
-		return nil, err
258
+		return nil, nil, err
259 259
 	}
260 260
 
261
+	// ValidateChain, if successful, will always return at least 1 parsed cert and at least 1 chain containing
262
+	// at least 2 certificates:  the leaf and the root.
263
+	leafCert := parsedCerts[0]
264
+	issuer := chains[0][1]
265
+
261 266
 	// Create a valid TLSKeyPair out of the PEM encoded private key and certificate
262 267
 	tlsKeyPair, err := tls.X509KeyPair(signedCert, key)
263 268
 	if err != nil {
264
-		return nil, err
269
+		return nil, nil, err
265 270
 	}
266 271
 
267 272
 	var kekUpdate *KEKData
268 273
 	for i := 0; i < 5; i++ {
269 274
 		// ValidateCertChain will always return at least 1 cert, so indexing at 0 is safe
270
-		kekUpdate, err = rca.getKEKUpdate(ctx, parsedCerts[0], tlsKeyPair, config.ConnBroker)
275
+		kekUpdate, err = rca.getKEKUpdate(ctx, leafCert, tlsKeyPair, config.ConnBroker)
271 276
 		if err == nil {
272 277
 			break
273 278
 		}
274 279
 	}
275 280
 	if err != nil {
276
-		return nil, err
281
+		return nil, nil, err
277 282
 	}
278 283
 
279
-	if err := kw.Write(signedCert, key, kekUpdate); err != nil {
280
-		return nil, err
284
+	if err := kw.Write(NormalizePEMs(signedCert), key, kekUpdate); err != nil {
285
+		return nil, nil, err
281 286
 	}
282 287
 
283
-	return &tlsKeyPair, nil
288
+	return &tlsKeyPair, &IssuerInfo{
289
+		PublicKey: issuer.RawSubjectPublicKeyInfo,
290
+		Subject:   issuer.RawSubject,
291
+	}, nil
284 292
 }
285 293
 
286 294
 func (rca *RootCA) getKEKUpdate(ctx context.Context, leafCert *x509.Certificate, keypair tls.Certificate, connBroker *connectionbroker.Broker) (*KEKData, error) {
... ...
@@ -430,7 +452,7 @@ func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry tim
430 430
 	var intermediatePool *x509.CertPool
431 431
 	var parsedIntermediates []*x509.Certificate
432 432
 	if len(intermediates) > 0 {
433
-		parsedIntermediates, err = ValidateCertChain(pool, intermediates, false)
433
+		parsedIntermediates, _, err = ValidateCertChain(pool, intermediates, false)
434 434
 		if err != nil {
435 435
 			return RootCA{}, errors.Wrap(err, "invalid intermediate chain")
436 436
 		}
... ...
@@ -469,15 +491,15 @@ func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry tim
469 469
 // intermediate pool), because this function is intended to be used when reading certs from untrusted locations such as
470 470
 // from disk or over a network when a CSR is signed, so it is extra pedantic.
471 471
 // This function always returns all the parsed certificates in the bundle in order, which means there will always be
472
-// at least 1 certificate if there is no error.
473
-func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, error) {
472
+// at least 1 certificate if there is no error, and the valid chains found by Certificate.Verify
473
+func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, [][]*x509.Certificate, error) {
474 474
 	// Parse all the certificates in the cert bundle
475 475
 	parsedCerts, err := helpers.ParseCertificatesPEM(certs)
476 476
 	if err != nil {
477
-		return nil, err
477
+		return nil, nil, err
478 478
 	}
479 479
 	if len(parsedCerts) == 0 {
480
-		return nil, errors.New("no certificates to validate")
480
+		return nil, nil, errors.New("no certificates to validate")
481 481
 	}
482 482
 	now := time.Now()
483 483
 	// ensure that they form a chain, each one being signed by the one after it
... ...
@@ -486,7 +508,7 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
486 486
 		// Manual expiry validation because we want more information on which certificate in the chain is expired, and
487 487
 		// because this is an easier way to allow expired certs.
488 488
 		if now.Before(cert.NotBefore) {
489
-			return nil, errors.Wrapf(
489
+			return nil, nil, errors.Wrapf(
490 490
 				x509.CertificateInvalidError{
491 491
 					Cert:   cert,
492 492
 					Reason: x509.Expired,
... ...
@@ -495,7 +517,7 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
495 495
 				i+1, cert.Subject.CommonName, cert.NotBefore.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
496 496
 		}
497 497
 		if !allowExpired && now.After(cert.NotAfter) {
498
-			return nil, errors.Wrapf(
498
+			return nil, nil, errors.Wrapf(
499 499
 				x509.CertificateInvalidError{
500 500
 					Cert:   cert,
501 501
 					Reason: x509.Expired,
... ...
@@ -508,7 +530,7 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
508 508
 			// check that the previous cert was signed by this cert
509 509
 			prevCert := parsedCerts[i-1]
510 510
 			if err := prevCert.CheckSignatureFrom(cert); err != nil {
511
-				return nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
511
+				return nil, nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
512 512
 					i, prevCert.Subject.CommonName, i+1, cert.Subject.CommonName)
513 513
 			}
514 514
 
... ...
@@ -526,6 +548,8 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
526 526
 		CurrentTime:   now,
527 527
 	}
528 528
 
529
+	var chains [][]*x509.Certificate
530
+
529 531
 	// If we accept expired certs, try to build a valid cert chain using some subset of the certs.  We start off using the
530 532
 	// first certificate's NotAfter as the current time, thus ensuring that the first cert is not expired. If the chain
531 533
 	// still fails to validate due to expiry issues, continue iterating over the rest of the certs.
... ...
@@ -540,22 +564,22 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
540 540
 			}
541 541
 			verifyOpts.CurrentTime = cert.NotAfter
542 542
 
543
-			_, err = parsedCerts[0].Verify(verifyOpts)
543
+			chains, err = parsedCerts[0].Verify(verifyOpts)
544 544
 			if err == nil {
545
-				return parsedCerts, nil
545
+				return parsedCerts, chains, nil
546 546
 			}
547 547
 		}
548 548
 		if invalid, ok := err.(x509.CertificateInvalidError); ok && invalid.Reason == x509.Expired {
549
-			return nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
549
+			return nil, nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
550 550
 		}
551
-		return nil, err
551
+		return nil, nil, err
552 552
 	}
553 553
 
554
-	_, err = parsedCerts[0].Verify(verifyOpts)
554
+	chains, err = parsedCerts[0].Verify(verifyOpts)
555 555
 	if err != nil {
556
-		return nil, err
556
+		return nil, nil, err
557 557
 	}
558
-	return parsedCerts, nil
558
+	return parsedCerts, chains, nil
559 559
 }
560 560
 
561 561
 // newLocalSigner validates the signing cert and signing key to create a local signer, which accepts a crypto signer and a cert
... ...
@@ -930,3 +954,22 @@ func EncryptECPrivateKey(key []byte, passphraseStr string) ([]byte, error) {
930 930
 
931 931
 	return pem.EncodeToMemory(encryptedPEMBlock), nil
932 932
 }
933
+
934
+// NormalizePEMs takes a bundle of PEM-encoded certificates in a certificate bundle,
935
+// decodes them, removes headers, and re-encodes them to make sure that they have
936
+// consistent whitespace.  Note that this is intended to normalize x509 certificates
937
+// in PEM format, hence the stripping out of headers.
938
+func NormalizePEMs(certs []byte) []byte {
939
+	var (
940
+		results  []byte
941
+		pemBlock *pem.Block
942
+	)
943
+	for {
944
+		pemBlock, certs = pem.Decode(bytes.TrimSpace(certs))
945
+		if pemBlock == nil {
946
+			return results
947
+		}
948
+		pemBlock.Headers = nil
949
+		results = append(results, pem.EncodeToMemory(pemBlock)...)
950
+	}
951
+}
... ...
@@ -19,6 +19,7 @@ import (
19 19
 	"github.com/docker/swarmkit/connectionbroker"
20 20
 	"github.com/docker/swarmkit/identity"
21 21
 	"github.com/docker/swarmkit/log"
22
+	"github.com/docker/swarmkit/watch"
22 23
 	"github.com/opencontainers/go-digest"
23 24
 	"github.com/pkg/errors"
24 25
 	"google.golang.org/grpc/credentials"
... ...
@@ -71,10 +72,16 @@ type SecurityConfig struct {
71 71
 	externalCA    *ExternalCA
72 72
 	keyReadWriter *KeyReadWriter
73 73
 
74
+	certificate *tls.Certificate
75
+	issuerInfo  *IssuerInfo
76
+
74 77
 	externalCAClientRootPool *x509.CertPool
75 78
 
76 79
 	ServerTLSCreds *MutableTLSCreds
77 80
 	ClientTLSCreds *MutableTLSCreds
81
+
82
+	// An optional queue for anyone interested in subscribing to SecurityConfig updates
83
+	queue *watch.Queue
78 84
 }
79 85
 
80 86
 // CertificateUpdate represents a change in the underlying TLS configuration being returned by
... ...
@@ -85,25 +92,41 @@ type CertificateUpdate struct {
85 85
 }
86 86
 
87 87
 // NewSecurityConfig initializes and returns a new SecurityConfig.
88
-func NewSecurityConfig(rootCA *RootCA, krw *KeyReadWriter, clientTLSCreds, serverTLSCreds *MutableTLSCreds) *SecurityConfig {
88
+func NewSecurityConfig(rootCA *RootCA, krw *KeyReadWriter, tlsKeyPair *tls.Certificate, issuerInfo *IssuerInfo) (*SecurityConfig, error) {
89
+	// Create the Server TLS Credentials for this node. These will not be used by workers.
90
+	serverTLSCreds, err := rootCA.NewServerTLSCredentials(tlsKeyPair)
91
+	if err != nil {
92
+		return nil, err
93
+	}
94
+
95
+	// Create a TLSConfig to be used when this node connects as a client to another remote node.
96
+	// We're using ManagerRole as remote serverName for TLS host verification because both workers
97
+	// and managers always connect to remote managers.
98
+	clientTLSCreds, err := rootCA.NewClientTLSCredentials(tlsKeyPair, ManagerRole)
99
+	if err != nil {
100
+		return nil, err
101
+	}
102
+
89 103
 	// Make a new TLS config for the external CA client without a
90 104
 	// ServerName value set.
91
-	clientTLSConfig := clientTLSCreds.Config()
92
-
93 105
 	externalCATLSConfig := &tls.Config{
94
-		Certificates: clientTLSConfig.Certificates,
95
-		RootCAs:      clientTLSConfig.RootCAs,
106
+		Certificates: []tls.Certificate{*tlsKeyPair},
107
+		RootCAs:      rootCA.Pool,
96 108
 		MinVersion:   tls.VersionTLS12,
97 109
 	}
98 110
 
99 111
 	return &SecurityConfig{
100
-		rootCA:                   rootCA,
101
-		keyReadWriter:            krw,
112
+		rootCA:        rootCA,
113
+		keyReadWriter: krw,
114
+
115
+		certificate: tlsKeyPair,
116
+		issuerInfo:  issuerInfo,
117
+
102 118
 		externalCA:               NewExternalCA(rootCA, externalCATLSConfig),
103 119
 		ClientTLSCreds:           clientTLSCreds,
104 120
 		ServerTLSCreds:           serverTLSCreds,
105 121
 		externalCAClientRootPool: rootCA.Pool,
106
-	}
122
+	}, nil
107 123
 }
108 124
 
109 125
 // RootCA returns the root CA.
... ...
@@ -136,19 +159,32 @@ func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA, externalCARootPool *x509.C
136 136
 
137 137
 	s.rootCA = rootCA
138 138
 	s.externalCAClientRootPool = externalCARootPool
139
-	clientTLSConfig := s.ClientTLSCreds.Config()
140
-	return s.updateTLSCredentials(clientTLSConfig.Certificates)
139
+	return s.updateTLSCredentials(s.certificate, s.issuerInfo)
140
+}
141
+
142
+// SetWatch allows you to set a watch on the security config, in order to be notified of any changes
143
+func (s *SecurityConfig) SetWatch(q *watch.Queue) {
144
+	s.mu.Lock()
145
+	defer s.mu.Unlock()
146
+	s.queue = q
147
+}
148
+
149
+// IssuerInfo returns the issuer subject and issuer public key
150
+func (s *SecurityConfig) IssuerInfo() *IssuerInfo {
151
+	s.mu.Lock()
152
+	defer s.mu.Unlock()
153
+	return s.issuerInfo
141 154
 }
142 155
 
143
-// updateTLSCredentials updates the client, server, and TLS credentials on a security config.  This function expects
144
-// something else to have taken out a lock on the SecurityConfig.
145
-func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) error {
146
-	clientConfig, err := NewClientTLSConfig(certificates, s.rootCA.Pool, ManagerRole)
156
+// This function expects something else to have taken out a lock on the SecurityConfig.
157
+func (s *SecurityConfig) updateTLSCredentials(certificate *tls.Certificate, issuerInfo *IssuerInfo) error {
158
+	certs := []tls.Certificate{*certificate}
159
+	clientConfig, err := NewClientTLSConfig(certs, s.rootCA.Pool, ManagerRole)
147 160
 	if err != nil {
148 161
 		return errors.Wrap(err, "failed to create a new client config using the new root CA")
149 162
 	}
150 163
 
151
-	serverConfig, err := NewServerTLSConfig(certificates, s.rootCA.Pool)
164
+	serverConfig, err := NewServerTLSConfig(certs, s.rootCA.Pool)
152 165
 	if err != nil {
153 166
 		return errors.Wrap(err, "failed to create a new server config using the new root CA")
154 167
 	}
... ...
@@ -160,7 +196,7 @@ func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) er
160 160
 	// Update the external CA to use the new client TLS
161 161
 	// config using a copy without a serverName specified.
162 162
 	s.externalCA.UpdateTLSConfig(&tls.Config{
163
-		Certificates: certificates,
163
+		Certificates: certs,
164 164
 		RootCAs:      s.externalCAClientRootPool,
165 165
 		MinVersion:   tls.VersionTLS12,
166 166
 	})
... ...
@@ -169,6 +205,15 @@ func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) er
169 169
 		return errors.Wrap(err, "failed to update the server TLS credentials")
170 170
 	}
171 171
 
172
+	s.certificate = certificate
173
+	s.issuerInfo = issuerInfo
174
+	if s.queue != nil {
175
+		s.queue.Publish(&api.NodeTLSInfo{
176
+			TrustRoot:           s.rootCA.Certs,
177
+			CertIssuerPublicKey: s.issuerInfo.PublicKey,
178
+			CertIssuerSubject:   s.issuerInfo.Subject,
179
+		})
180
+	}
172 181
 	return nil
173 182
 }
174 183
 
... ...
@@ -300,9 +345,13 @@ func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter,
300 300
 	}
301 301
 
302 302
 	// Check to see if this certificate was signed by our CA, and isn't expired
303
-	if _, err := ValidateCertChain(rootCA.Pool, cert, allowExpired); err != nil {
303
+	_, chains, err := ValidateCertChain(rootCA.Pool, cert, allowExpired)
304
+	if err != nil {
304 305
 		return nil, err
305 306
 	}
307
+	// ValidateChain, if successful, will always return at least 1 chain containing
308
+	// at least 2 certificates:  the leaf and the root.
309
+	issuer := chains[0][1]
306 310
 
307 311
 	// Now that we know this certificate is valid, create a TLS Certificate for our
308 312
 	// credentials
... ...
@@ -311,26 +360,17 @@ func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter,
311 311
 		return nil, err
312 312
 	}
313 313
 
314
-	// Load the Certificates as server credentials
315
-	serverTLSCreds, err := rootCA.NewServerTLSCredentials(&keyPair)
316
-	if err != nil {
317
-		return nil, err
318
-	}
319
-
320
-	// Load the Certificates also as client credentials.
321
-	// Both workers and managers always connect to remote managers,
322
-	// so ServerName is always set to ManagerRole here.
323
-	clientTLSCreds, err := rootCA.NewClientTLSCredentials(&keyPair, ManagerRole)
324
-	if err != nil {
325
-		return nil, err
314
+	secConfig, err := NewSecurityConfig(&rootCA, krw, &keyPair, &IssuerInfo{
315
+		Subject:   issuer.RawSubject,
316
+		PublicKey: issuer.RawSubjectPublicKeyInfo,
317
+	})
318
+	if err == nil {
319
+		log.G(ctx).WithFields(logrus.Fields{
320
+			"node.id":   secConfig.ClientTLSCreds.NodeID(),
321
+			"node.role": secConfig.ClientTLSCreds.Role(),
322
+		}).Debug("loaded node credentials")
326 323
 	}
327
-
328
-	log.G(ctx).WithFields(logrus.Fields{
329
-		"node.id":   clientTLSCreds.NodeID(),
330
-		"node.role": clientTLSCreds.Role(),
331
-	}).Debug("loaded node credentials")
332
-
333
-	return NewSecurityConfig(&rootCA, krw, clientTLSCreds, serverTLSCreds), nil
324
+	return secConfig, err
334 325
 }
335 326
 
336 327
 // CertificateRequestConfig contains the information needed to request a
... ...
@@ -365,12 +405,12 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite
365 365
 	org := identity.NewID()
366 366
 
367 367
 	proposedRole := ManagerRole
368
-	tlsKeyPair, err := rootCA.IssueAndSaveNewCertificates(krw, cn, proposedRole, org)
368
+	tlsKeyPair, issuerInfo, err := rootCA.IssueAndSaveNewCertificates(krw, cn, proposedRole, org)
369 369
 	switch errors.Cause(err) {
370 370
 	case ErrNoValidSigner:
371 371
 		// Request certificate issuance from a remote CA.
372 372
 		// Last argument is nil because at this point we don't have any valid TLS creds
373
-		tlsKeyPair, err = rootCA.RequestAndSaveNewCertificates(ctx, krw, config)
373
+		tlsKeyPair, issuerInfo, err = rootCA.RequestAndSaveNewCertificates(ctx, krw, config)
374 374
 		if err != nil {
375 375
 			log.G(ctx).WithError(err).Error("failed to request save new certificate")
376 376
 			return nil, err
... ...
@@ -388,24 +428,14 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite
388 388
 		return nil, err
389 389
 	}
390 390
 
391
-	// Create the Server TLS Credentials for this node. These will not be used by workers.
392
-	serverTLSCreds, err := rootCA.NewServerTLSCredentials(tlsKeyPair)
393
-	if err != nil {
394
-		return nil, err
395
-	}
396
-
397
-	// Create a TLSConfig to be used when this node connects as a client to another remote node.
398
-	// We're using ManagerRole as remote serverName for TLS host verification
399
-	clientTLSCreds, err := rootCA.NewClientTLSCredentials(tlsKeyPair, ManagerRole)
400
-	if err != nil {
401
-		return nil, err
391
+	secConfig, err := NewSecurityConfig(&rootCA, krw, tlsKeyPair, issuerInfo)
392
+	if err == nil {
393
+		log.G(ctx).WithFields(logrus.Fields{
394
+			"node.id":   secConfig.ClientTLSCreds.NodeID(),
395
+			"node.role": secConfig.ClientTLSCreds.Role(),
396
+		}).Debugf("new node credentials generated: %s", krw.Target())
402 397
 	}
403
-	log.G(ctx).WithFields(logrus.Fields{
404
-		"node.id":   clientTLSCreds.NodeID(),
405
-		"node.role": clientTLSCreds.Role(),
406
-	}).Debugf("new node credentials generated: %s", krw.Target())
407
-
408
-	return NewSecurityConfig(&rootCA, krw, clientTLSCreds, serverTLSCreds), nil
398
+	return secConfig, err
409 399
 }
410 400
 
411 401
 // RenewTLSConfigNow gets a new TLS cert and key, and updates the security config if provided.  This is similar to
... ...
@@ -422,7 +452,7 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne
422 422
 
423 423
 	// Let's request new certs. Renewals don't require a token.
424 424
 	rootCA := s.RootCA()
425
-	tlsKeyPair, err := rootCA.RequestAndSaveNewCertificates(ctx,
425
+	tlsKeyPair, issuerInfo, err := rootCA.RequestAndSaveNewCertificates(ctx,
426 426
 		s.KeyWriter(),
427 427
 		CertificateRequestConfig{
428 428
 			ConnBroker:  connBroker,
... ...
@@ -432,9 +462,10 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne
432 432
 		log.WithError(err).Errorf("failed to renew the certificate")
433 433
 		return err
434 434
 	}
435
+
435 436
 	s.mu.Lock()
436 437
 	defer s.mu.Unlock()
437
-	return s.updateTLSCredentials([]tls.Certificate{*tlsKeyPair})
438
+	return s.updateTLSCredentials(tlsKeyPair, issuerInfo)
438 439
 }
439 440
 
440 441
 // RenewTLSConfig will continuously monitor for the necessity of renewing the local certificates, either by
... ...
@@ -60,6 +60,9 @@ type Server struct {
60 60
 	lastSeenClusterRootCA *api.RootCA
61 61
 	lastSeenExternalCAs   []*api.ExternalCA
62 62
 	secConfigMu           sync.Mutex
63
+
64
+	// before we update the security config with the new root CA, we need to be able to save the root certs
65
+	rootPaths CertPaths
63 66
 }
64 67
 
65 68
 // DefaultCAConfig returns the default CA Config, with a default expiration.
... ...
@@ -70,13 +73,14 @@ func DefaultCAConfig() api.CAConfig {
70 70
 }
71 71
 
72 72
 // NewServer creates a CA API server.
73
-func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig) *Server {
73
+func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig, rootCAPaths CertPaths) *Server {
74 74
 	return &Server{
75 75
 		store:                       store,
76 76
 		securityConfig:              securityConfig,
77 77
 		pending:                     make(map[string]*api.Node),
78 78
 		started:                     make(chan struct{}),
79 79
 		reconciliationRetryInterval: defaultReconciliationRetryInterval,
80
+		rootPaths:                   rootCAPaths,
80 81
 	}
81 82
 }
82 83
 
... ...
@@ -582,6 +586,9 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
582 582
 		if err != nil {
583 583
 			return errors.Wrap(err, "invalid Root CA object in cluster")
584 584
 		}
585
+		if err := SaveRootCA(updatedRootCA, s.rootPaths); err != nil {
586
+			return errors.Wrap(err, "unable to save new root CA certificates")
587
+		}
585 588
 
586 589
 		externalCARootPool := updatedRootCA.Pool
587 590
 		if rCA.RootRotation != nil {
... ...
@@ -609,6 +616,7 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
609 609
 			// we're rotating to a new root, so we only want external CAs with the new root cert
610 610
 			wantedExternalCACert = rCA.RootRotation.CACert
611 611
 		}
612
+		wantedExternalCACert = NormalizePEMs(wantedExternalCACert)
612 613
 		// Update our security config with the list of External CA URLs
613 614
 		// from the new cluster state.
614 615
 
... ...
@@ -623,6 +631,7 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
623 623
 			if len(certForExtCA) == 0 {
624 624
 				certForExtCA = rCA.CACert
625 625
 			}
626
+			certForExtCA = NormalizePEMs(certForExtCA)
626 627
 			if extCA.Protocol != api.ExternalCA_CAProtocolCFSSL {
627 628
 				logger.Debugf("skipping external CA %d (url: %s) due to unknown protocol type", i, extCA.URL)
628 629
 				continue
... ...
@@ -24,28 +24,28 @@ var minRootExpiration = 1 * helpers.OneYear
24 24
 // determines whether an api.RootCA, api.RootRotation, or api.CAConfig has a signing key (local signer)
25 25
 func hasSigningKey(a interface{}) bool {
26 26
 	switch b := a.(type) {
27
-	case api.RootCA:
27
+	case *api.RootCA:
28 28
 		return len(b.CAKey) > 0
29 29
 	case *api.RootRotation:
30 30
 		return b != nil && len(b.CAKey) > 0
31
-	case api.CAConfig:
31
+	case *api.CAConfig:
32 32
 		return len(b.SigningCACert) > 0 && len(b.SigningCAKey) > 0
33 33
 	default:
34
-		panic("needsExternalCAs should be called something of type api.RootCA, *api.RootRotation, or api.CAConfig")
34
+		panic("needsExternalCAs should be called something of type *api.RootCA, *api.RootRotation, or *api.CAConfig")
35 35
 	}
36 36
 }
37 37
 
38 38
 // Creates a cross-signed intermediate and new api.RootRotation object.
39 39
 // This function assumes that the root cert and key and the external CAs have already been validated.
40
-func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfig, cluster *api.Cluster, newRootCA ca.RootCA, version uint64) (*api.RootCA, error) {
40
+func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfig, apiRootCA *api.RootCA, newCARootCA ca.RootCA, extCAs []*api.ExternalCA, version uint64) (*api.RootCA, error) {
41 41
 	var (
42 42
 		rootCert, rootKey, crossSignedCert []byte
43 43
 		newRootHasSigner                   bool
44 44
 		err                                error
45 45
 	)
46 46
 
47
-	rootCert = newRootCA.Certs
48
-	if s, err := newRootCA.Signer(); err == nil {
47
+	rootCert = newCARootCA.Certs
48
+	if s, err := newCARootCA.Signer(); err == nil {
49 49
 		rootCert, rootKey = s.Cert, s.Key
50 50
 		newRootHasSigner = true
51 51
 	}
... ...
@@ -53,9 +53,9 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
53 53
 	// we have to sign with the original signer, not whatever is in the SecurityConfig's RootCA (which may have an intermediate signer, if
54 54
 	// a root rotation is already in progress)
55 55
 	switch {
56
-	case hasSigningKey(cluster.RootCA):
56
+	case hasSigningKey(apiRootCA):
57 57
 		var oldRootCA ca.RootCA
58
-		oldRootCA, err = ca.NewRootCA(cluster.RootCA.CACert, cluster.RootCA.CACert, cluster.RootCA.CAKey, ca.DefaultNodeCertExpiration, nil)
58
+		oldRootCA, err = ca.NewRootCA(apiRootCA.CACert, apiRootCA.CACert, apiRootCA.CAKey, ca.DefaultNodeCertExpiration, nil)
59 59
 		if err == nil {
60 60
 			crossSignedCert, err = oldRootCA.CrossSignCACertificate(rootCert)
61 61
 		}
... ...
@@ -65,8 +65,8 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
65 65
 		// We need the same credentials but to connect to the original URLs (in case we are in the middle of a root rotation already)
66 66
 		externalCA := securityConfig.ExternalCA().Copy()
67 67
 		var urls []string
68
-		for _, c := range cluster.Spec.CAConfig.ExternalCAs {
69
-			if c.Protocol == api.ExternalCA_CAProtocolCFSSL && bytes.Equal(c.CACert, cluster.RootCA.CACert) {
68
+		for _, c := range extCAs {
69
+			if c.Protocol == api.ExternalCA_CAProtocolCFSSL {
70 70
 				urls = append(urls, c.URL)
71 71
 			}
72 72
 		}
... ...
@@ -75,7 +75,7 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
75 75
 				"must provide an external CA for the current external root CA to generate a cross-signed certificate")
76 76
 		}
77 77
 		externalCA.UpdateURLs(urls...)
78
-		crossSignedCert, err = externalCA.CrossSignRootCA(ctx, newRootCA)
78
+		crossSignedCert, err = externalCA.CrossSignRootCA(ctx, newCARootCA)
79 79
 	}
80 80
 
81 81
 	if err != nil {
... ...
@@ -83,11 +83,11 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
83 83
 		return nil, grpc.Errorf(codes.Internal, "unable to generate a cross-signed certificate for root rotation")
84 84
 	}
85 85
 
86
-	copied := cluster.RootCA.Copy()
86
+	copied := apiRootCA.Copy()
87 87
 	copied.RootRotation = &api.RootRotation{
88 88
 		CACert:            rootCert,
89 89
 		CAKey:             rootKey,
90
-		CrossSignedCACert: crossSignedCert,
90
+		CrossSignedCACert: ca.NormalizePEMs(crossSignedCert),
91 91
 	}
92 92
 	copied.LastForcedRotation = version
93 93
 	return copied, nil
... ...
@@ -120,58 +120,46 @@ func validateExternalCAURL(dialer *net.Dialer, tlsOpts *tls.Config, caURL string
120 120
 	return err
121 121
 }
122 122
 
123
-// Iterates over all the external CAs, and validates that there is at least 1 reachable, valid external CA for the
124
-// given CA certificate.  Returns true if there is, false otherwise.
125
-func hasAtLeastOneExternalCA(ctx context.Context, externalCAs []*api.ExternalCA, securityConfig *ca.SecurityConfig, wantedCert []byte) bool {
126
-	pool := x509.NewCertPool()
127
-	pool.AppendCertsFromPEM(wantedCert)
128
-	dialer := net.Dialer{Timeout: 5 * time.Second}
129
-	opts := tls.Config{
130
-		RootCAs:      pool,
131
-		Certificates: securityConfig.ClientTLSCreds.Config().Certificates,
132
-	}
133
-	for i, ca := range externalCAs {
134
-		if ca.Protocol == api.ExternalCA_CAProtocolCFSSL && bytes.Equal(wantedCert, ca.CACert) {
135
-			err := validateExternalCAURL(&dialer, &opts, ca.URL)
136
-			if err == nil {
137
-				return true
123
+// Validates that there is at least 1 reachable, valid external CA for the given CA certificate.  Returns true if there is, false otherwise.
124
+// Requires that the wanted cert is already normalized.
125
+func validateHasAtLeastOneExternalCA(ctx context.Context, externalCAs map[string][]*api.ExternalCA, securityConfig *ca.SecurityConfig,
126
+	wantedCert []byte, desc string) ([]*api.ExternalCA, error) {
127
+	specific, ok := externalCAs[string(wantedCert)]
128
+	if ok {
129
+		pool := x509.NewCertPool()
130
+		pool.AppendCertsFromPEM(wantedCert)
131
+		dialer := net.Dialer{Timeout: 5 * time.Second}
132
+		opts := tls.Config{
133
+			RootCAs:      pool,
134
+			Certificates: securityConfig.ClientTLSCreds.Config().Certificates,
135
+		}
136
+		for i, ca := range specific {
137
+			if ca.Protocol == api.ExternalCA_CAProtocolCFSSL {
138
+				if err := validateExternalCAURL(&dialer, &opts, ca.URL); err != nil {
139
+					log.G(ctx).WithError(err).Warnf("external CA # %d is unreachable or invalid", i+1)
140
+				} else {
141
+					return specific, nil
142
+				}
138 143
 			}
139
-			log.G(ctx).WithError(err).Warnf("external CA # %d is unreachable or invalid", i+1)
140 144
 		}
141 145
 	}
142
-	return false
146
+	return nil, grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the %s CA certificate", desc)
143 147
 }
144 148
 
145
-// All new external CA definitions must include the CA cert associated with the external CA.
146
-// If the current root CA requires an external CA, then at least one, reachable valid external CA must be provided that
147
-// corresponds with the current RootCA's certificate.
148
-//
149
-// Similarly for the desired CA certificate, if one is specified.  Similarly for the current outstanding root CA rotation,
150
-// if one is specified and will not be replaced with the desired CA.
151
-func validateHasRequiredExternalCAs(ctx context.Context, securityConfig *ca.SecurityConfig, cluster *api.Cluster) error {
152
-	config := cluster.Spec.CAConfig
153
-	for _, ca := range config.ExternalCAs {
154
-		if len(ca.CACert) == 0 {
155
-			return grpc.Errorf(codes.InvalidArgument, "must specify CA certificate for each external CA")
156
-		}
157
-	}
158
-
159
-	if !hasSigningKey(cluster.RootCA) && !hasAtLeastOneExternalCA(ctx, config.ExternalCAs, securityConfig, cluster.RootCA.CACert) {
160
-		return grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the current CA certificate")
161
-	}
149
+// validates that the list of external CAs have valid certs associated with them, and produce a mapping of subject/pubkey:external
150
+// for later validation of required external CAs
151
+func getNormalizedExtCAs(caConfig *api.CAConfig) (map[string][]*api.ExternalCA, error) {
152
+	extCAs := make(map[string][]*api.ExternalCA)
162 153
 
163
-	if len(config.SigningCACert) > 0 { // a signing cert is specified
164
-		if !hasSigningKey(config) && !hasAtLeastOneExternalCA(ctx, config.ExternalCAs, securityConfig, config.SigningCACert) {
165
-			return grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the desired CA certificate")
166
-		}
167
-	} else if config.ForceRotate == cluster.RootCA.LastForcedRotation && cluster.RootCA.RootRotation != nil {
168
-		// no cert is specified but force rotation hasn't changed (so we are happy with the current configuration) and there's an outstanding root rotation
169
-		if !hasSigningKey(cluster.RootCA.RootRotation) && !hasAtLeastOneExternalCA(ctx, config.ExternalCAs, securityConfig, cluster.RootCA.RootRotation.CACert) {
170
-			return grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the next CA certificate")
154
+	for _, extCA := range caConfig.ExternalCAs {
155
+		if len(extCA.CACert) == 0 {
156
+			return nil, grpc.Errorf(codes.InvalidArgument, "must specify CA certificate for each external CA")
171 157
 		}
158
+		certKey := string(ca.NormalizePEMs(extCA.CACert))
159
+		extCAs[certKey] = append(extCAs[certKey], extCA)
172 160
 	}
173 161
 
174
-	return nil
162
+	return extCAs, nil
175 163
 }
176 164
 
177 165
 // validateAndUpdateCA validates a cluster's desired CA configuration spec, and returns a RootCA value on success representing
... ...
@@ -196,16 +184,27 @@ func validateHasRequiredExternalCAs(ctx context.Context, securityConfig *ca.Secu
196 196
 //    - Otherwise, start a new root rotation using the desired signing cert and desired signing key as the root rotation
197 197
 //      signing cert and key.  If a root rotation is already in progress, just replace it and start over.
198 198
 func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cluster *api.Cluster) (*api.RootCA, error) {
199
-	newConfig := cluster.Spec.CAConfig
199
+	newConfig := cluster.Spec.CAConfig.Copy()
200
+	newConfig.SigningCACert = ca.NormalizePEMs(newConfig.SigningCACert) // ensure this is normalized before we use it
200 201
 
201 202
 	if len(newConfig.SigningCAKey) > 0 && len(newConfig.SigningCACert) == 0 {
202 203
 		return nil, grpc.Errorf(codes.InvalidArgument, "if a signing CA key is provided, the signing CA cert must also be provided")
203 204
 	}
204 205
 
205
-	if err := validateHasRequiredExternalCAs(ctx, securityConfig, cluster); err != nil {
206
+	extCAs, err := getNormalizedExtCAs(newConfig) // validate that the list of external CAs is not malformed
207
+	if err != nil {
206 208
 		return nil, err
207 209
 	}
208 210
 
211
+	normalizedRootCA := ca.NormalizePEMs(cluster.RootCA.CACert)
212
+	var oldCertExtCAs []*api.ExternalCA
213
+	if !hasSigningKey(&cluster.RootCA) {
214
+		oldCertExtCAs, err = validateHasAtLeastOneExternalCA(ctx, extCAs, securityConfig, normalizedRootCA, "current")
215
+		if err != nil {
216
+			return nil, err
217
+		}
218
+	}
219
+
209 220
 	// if the desired CA cert and key are not set, then we are happy with the current root CA configuration, unless
210 221
 	// the ForceRotate version has changed
211 222
 	if len(newConfig.SigningCACert) == 0 {
... ...
@@ -214,8 +213,18 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
214 214
 			if err != nil {
215 215
 				return nil, grpc.Errorf(codes.Internal, err.Error())
216 216
 			}
217
-			return newRootRotationObject(ctx, securityConfig, cluster, newRootCA, newConfig.ForceRotate)
217
+			return newRootRotationObject(ctx, securityConfig, &cluster.RootCA, newRootCA, oldCertExtCAs, newConfig.ForceRotate)
218
+		}
219
+
220
+		// we also need to make sure that if the current root rotation requires an external CA, those external CAs are
221
+		// still valid
222
+		if cluster.RootCA.RootRotation != nil && !hasSigningKey(cluster.RootCA.RootRotation) {
223
+			_, err := validateHasAtLeastOneExternalCA(ctx, extCAs, securityConfig, ca.NormalizePEMs(cluster.RootCA.RootRotation.CACert), "next")
224
+			if err != nil {
225
+				return nil, err
226
+			}
218 227
 		}
228
+
219 229
 		return &cluster.RootCA, nil // no change, return as is
220 230
 	}
221 231
 
... ...
@@ -243,8 +252,14 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
243 243
 		return nil, grpc.Errorf(codes.InvalidArgument, "CA certificate expires too soon")
244 244
 	}
245 245
 
246
+	if !hasSigningKey(newConfig) {
247
+		if _, err := validateHasAtLeastOneExternalCA(ctx, extCAs, securityConfig, newConfig.SigningCACert, "desired"); err != nil {
248
+			return nil, err
249
+		}
250
+	}
251
+
246 252
 	// check if we can abort any existing root rotations
247
-	if bytes.Equal(cluster.RootCA.CACert, cluster.Spec.CAConfig.SigningCACert) {
253
+	if bytes.Equal(normalizedRootCA, newConfig.SigningCACert) {
248 254
 		copied := cluster.RootCA.Copy()
249 255
 		copied.CAKey = newConfig.SigningCAKey
250 256
 		copied.RootRotation = nil
... ...
@@ -253,7 +268,7 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
253 253
 	}
254 254
 
255 255
 	// check if this is the same desired cert as an existing root rotation
256
-	if r := cluster.RootCA.RootRotation; r != nil && bytes.Equal(r.CACert, cluster.Spec.CAConfig.SigningCACert) {
256
+	if r := cluster.RootCA.RootRotation; r != nil && bytes.Equal(ca.NormalizePEMs(r.CACert), newConfig.SigningCACert) {
257 257
 		copied := cluster.RootCA.Copy()
258 258
 		copied.RootRotation.CAKey = newConfig.SigningCAKey
259 259
 		copied.LastForcedRotation = newConfig.ForceRotate
... ...
@@ -261,5 +276,5 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
261 261
 	}
262 262
 
263 263
 	// ok, everything's different; we have to begin a new root rotation which means generating a new cross-signed cert
264
-	return newRootRotationObject(ctx, securityConfig, cluster, newRootCA, newConfig.ForceRotate)
264
+	return newRootRotationObject(ctx, securityConfig, &cluster.RootCA, newRootCA, oldCertExtCAs, newConfig.ForceRotate)
265 265
 }
... ...
@@ -38,7 +38,7 @@ func validateClusterSpec(spec *api.ClusterSpec) error {
38 38
 	}
39 39
 
40 40
 	// Validate that AcceptancePolicies only include Secrets that are bcrypted
41
-	// TODO(diogo): Add a global list of acceptace algorithms. We only support bcrypt for now.
41
+	// TODO(diogo): Add a global list of acceptance algorithms. We only support bcrypt for now.
42 42
 	if len(spec.AcceptancePolicy.Policies) > 0 {
43 43
 		for _, policy := range spec.AcceptancePolicy.Policies {
44 44
 			if policy.Secret != nil && strings.ToLower(policy.Secret.Alg) != "bcrypt" {
... ...
@@ -13,7 +13,10 @@ import (
13 13
 	"google.golang.org/grpc/codes"
14 14
 )
15 15
 
16
-var isValidName = regexp.MustCompile(`^[a-zA-Z0-9](?:[-_]*[A-Za-z0-9]+)*$`)
16
+var isValidDNSName = regexp.MustCompile(`^[a-zA-Z0-9](?:[-_]*[A-Za-z0-9]+)*$`)
17
+
18
+// configs and secrets have different naming requirements from tasks and services
19
+var isValidConfigOrSecretName = regexp.MustCompile(`^[a-zA-Z0-9]+(?:[a-zA-Z0-9-_.]*[a-zA-Z0-9])?$`)
17 20
 
18 21
 func buildFilters(by func(string) store.By, values []string) store.By {
19 22
 	filters := make([]store.By, 0, len(values))
... ...
@@ -68,7 +71,7 @@ func validateAnnotations(m api.Annotations) error {
68 68
 	if m.Name == "" {
69 69
 		return grpc.Errorf(codes.InvalidArgument, "meta: name must be provided")
70 70
 	}
71
-	if !isValidName.MatchString(m.Name) {
71
+	if !isValidDNSName.MatchString(m.Name) {
72 72
 		// if the name doesn't match the regex
73 73
 		return grpc.Errorf(codes.InvalidArgument, "name must be valid as a DNS name component")
74 74
 	}
... ...
@@ -79,6 +82,17 @@ func validateAnnotations(m api.Annotations) error {
79 79
 	return nil
80 80
 }
81 81
 
82
+func validateConfigOrSecretAnnotations(m api.Annotations) error {
83
+	if m.Name == "" {
84
+		return grpc.Errorf(codes.InvalidArgument, "name must be provided")
85
+	} else if len(m.Name) > 64 || !isValidConfigOrSecretName.MatchString(m.Name) {
86
+		// if the name doesn't match the regex
87
+		return grpc.Errorf(codes.InvalidArgument,
88
+			"invalid name, only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]")
89
+	}
90
+	return nil
91
+}
92
+
82 93
 func validateDriver(driver *api.Driver, pg plugingetter.PluginGetter, pluginType string) error {
83 94
 	if driver == nil {
84 95
 		// It is ok to not specify the driver. We will choose
85 96
new file mode 100644
... ...
@@ -0,0 +1,248 @@
0
+package controlapi
1
+
2
+import (
3
+	"bytes"
4
+	"strings"
5
+
6
+	"github.com/Sirupsen/logrus"
7
+	"github.com/docker/swarmkit/api"
8
+	"github.com/docker/swarmkit/identity"
9
+	"github.com/docker/swarmkit/log"
10
+	"github.com/docker/swarmkit/manager/state/store"
11
+	"golang.org/x/net/context"
12
+	"google.golang.org/grpc"
13
+	"google.golang.org/grpc/codes"
14
+)
15
+
16
+// MaxConfigSize is the maximum byte length of the `Config.Spec.Data` field.
17
+const MaxConfigSize = 500 * 1024 // 500KB
18
+
19
+// assumes spec is not nil
20
+func configFromConfigSpec(spec *api.ConfigSpec) *api.Config {
21
+	return &api.Config{
22
+		ID:   identity.NewID(),
23
+		Spec: *spec,
24
+	}
25
+}
26
+
27
+// GetConfig returns a `GetConfigResponse` with a `Config` with the same
28
+// id as `GetConfigRequest.ConfigID`
29
+// - Returns `NotFound` if the Config with the given id is not found.
30
+// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
31
+// - Returns an error if getting fails.
32
+func (s *Server) GetConfig(ctx context.Context, request *api.GetConfigRequest) (*api.GetConfigResponse, error) {
33
+	if request.ConfigID == "" {
34
+		return nil, grpc.Errorf(codes.InvalidArgument, "config ID must be provided")
35
+	}
36
+
37
+	var config *api.Config
38
+	s.store.View(func(tx store.ReadTx) {
39
+		config = store.GetConfig(tx, request.ConfigID)
40
+	})
41
+
42
+	if config == nil {
43
+		return nil, grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
44
+	}
45
+
46
+	return &api.GetConfigResponse{Config: config}, nil
47
+}
48
+
49
+// UpdateConfig updates a Config referenced by ConfigID with the given ConfigSpec.
50
+// - Returns `NotFound` if the Config is not found.
51
+// - Returns `InvalidArgument` if the ConfigSpec is malformed or anything other than Labels is changed
52
+// - Returns an error if the update fails.
53
+func (s *Server) UpdateConfig(ctx context.Context, request *api.UpdateConfigRequest) (*api.UpdateConfigResponse, error) {
54
+	if request.ConfigID == "" || request.ConfigVersion == nil {
55
+		return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
56
+	}
57
+
58
+	var config *api.Config
59
+	err := s.store.Update(func(tx store.Tx) error {
60
+		config = store.GetConfig(tx, request.ConfigID)
61
+		if config == nil {
62
+			return grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
63
+		}
64
+
65
+		// Check if the Name is different than the current name, or the config is non-nil and different
66
+		// than the current config
67
+		if config.Spec.Annotations.Name != request.Spec.Annotations.Name ||
68
+			(request.Spec.Data != nil && !bytes.Equal(request.Spec.Data, config.Spec.Data)) {
69
+			return grpc.Errorf(codes.InvalidArgument, "only updates to Labels are allowed")
70
+		}
71
+
72
+		// We only allow updating Labels
73
+		config.Meta.Version = *request.ConfigVersion
74
+		config.Spec.Annotations.Labels = request.Spec.Annotations.Labels
75
+
76
+		return store.UpdateConfig(tx, config)
77
+	})
78
+	if err != nil {
79
+		return nil, err
80
+	}
81
+
82
+	log.G(ctx).WithFields(logrus.Fields{
83
+		"config.ID":   request.ConfigID,
84
+		"config.Name": request.Spec.Annotations.Name,
85
+		"method":      "UpdateConfig",
86
+	}).Debugf("config updated")
87
+
88
+	return &api.UpdateConfigResponse{
89
+		Config: config,
90
+	}, nil
91
+}
92
+
93
+// ListConfigs returns a `ListConfigResponse` with a list all non-internal `Config`s being
94
+// managed, or all configs matching any name in `ListConfigsRequest.Names`, any
95
+// name prefix in `ListConfigsRequest.NamePrefixes`, any id in
96
+// `ListConfigsRequest.ConfigIDs`, or any id prefix in `ListConfigsRequest.IDPrefixes`.
97
+// - Returns an error if listing fails.
98
+func (s *Server) ListConfigs(ctx context.Context, request *api.ListConfigsRequest) (*api.ListConfigsResponse, error) {
99
+	var (
100
+		configs     []*api.Config
101
+		respConfigs []*api.Config
102
+		err         error
103
+		byFilters   []store.By
104
+		by          store.By
105
+		labels      map[string]string
106
+	)
107
+
108
+	// return all configs that match either any of the names or any of the name prefixes (why would you give both?)
109
+	if request.Filters != nil {
110
+		for _, name := range request.Filters.Names {
111
+			byFilters = append(byFilters, store.ByName(name))
112
+		}
113
+		for _, prefix := range request.Filters.NamePrefixes {
114
+			byFilters = append(byFilters, store.ByNamePrefix(prefix))
115
+		}
116
+		for _, prefix := range request.Filters.IDPrefixes {
117
+			byFilters = append(byFilters, store.ByIDPrefix(prefix))
118
+		}
119
+		labels = request.Filters.Labels
120
+	}
121
+
122
+	switch len(byFilters) {
123
+	case 0:
124
+		by = store.All
125
+	case 1:
126
+		by = byFilters[0]
127
+	default:
128
+		by = store.Or(byFilters...)
129
+	}
130
+
131
+	s.store.View(func(tx store.ReadTx) {
132
+		configs, err = store.FindConfigs(tx, by)
133
+	})
134
+	if err != nil {
135
+		return nil, err
136
+	}
137
+
138
+	// filter by label
139
+	for _, config := range configs {
140
+		if !filterMatchLabels(config.Spec.Annotations.Labels, labels) {
141
+			continue
142
+		}
143
+		respConfigs = append(respConfigs, config)
144
+	}
145
+
146
+	return &api.ListConfigsResponse{Configs: respConfigs}, nil
147
+}
148
+
149
+// CreateConfig creates and returns a `CreateConfigResponse` with a `Config` based
150
+// on the provided `CreateConfigRequest.ConfigSpec`.
151
+// - Returns `InvalidArgument` if the `CreateConfigRequest.ConfigSpec` is malformed,
152
+//   or if the config data is too long or contains invalid characters.
153
+// - Returns an error if the creation fails.
154
+func (s *Server) CreateConfig(ctx context.Context, request *api.CreateConfigRequest) (*api.CreateConfigResponse, error) {
155
+	if err := validateConfigSpec(request.Spec); err != nil {
156
+		return nil, err
157
+	}
158
+
159
+	config := configFromConfigSpec(request.Spec) // the store will handle name conflicts
160
+	err := s.store.Update(func(tx store.Tx) error {
161
+		return store.CreateConfig(tx, config)
162
+	})
163
+
164
+	switch err {
165
+	case store.ErrNameConflict:
166
+		return nil, grpc.Errorf(codes.AlreadyExists, "config %s already exists", request.Spec.Annotations.Name)
167
+	case nil:
168
+		log.G(ctx).WithFields(logrus.Fields{
169
+			"config.Name": request.Spec.Annotations.Name,
170
+			"method":      "CreateConfig",
171
+		}).Debugf("config created")
172
+
173
+		return &api.CreateConfigResponse{Config: config}, nil
174
+	default:
175
+		return nil, err
176
+	}
177
+}
178
+
179
+// RemoveConfig removes the config referenced by `RemoveConfigRequest.ID`.
180
+// - Returns `InvalidArgument` if `RemoveConfigRequest.ID` is empty.
181
+// - Returns `NotFound` if the a config named `RemoveConfigRequest.ID` is not found.
182
+// - Returns `ConfigInUse` if the config is currently in use
183
+// - Returns an error if the deletion fails.
184
+func (s *Server) RemoveConfig(ctx context.Context, request *api.RemoveConfigRequest) (*api.RemoveConfigResponse, error) {
185
+	if request.ConfigID == "" {
186
+		return nil, grpc.Errorf(codes.InvalidArgument, "config ID must be provided")
187
+	}
188
+
189
+	err := s.store.Update(func(tx store.Tx) error {
190
+		// Check if the config exists
191
+		config := store.GetConfig(tx, request.ConfigID)
192
+		if config == nil {
193
+			return grpc.Errorf(codes.NotFound, "could not find config %s", request.ConfigID)
194
+		}
195
+
196
+		// Check if any services currently reference this config, return error if so
197
+		services, err := store.FindServices(tx, store.ByReferencedConfigID(request.ConfigID))
198
+		if err != nil {
199
+			return grpc.Errorf(codes.Internal, "could not find services using config %s: %v", request.ConfigID, err)
200
+		}
201
+
202
+		if len(services) != 0 {
203
+			serviceNames := make([]string, 0, len(services))
204
+			for _, service := range services {
205
+				serviceNames = append(serviceNames, service.Spec.Annotations.Name)
206
+			}
207
+
208
+			configName := config.Spec.Annotations.Name
209
+			serviceNameStr := strings.Join(serviceNames, ", ")
210
+			serviceStr := "services"
211
+			if len(serviceNames) == 1 {
212
+				serviceStr = "service"
213
+			}
214
+
215
+			return grpc.Errorf(codes.InvalidArgument, "config '%s' is in use by the following %s: %v", configName, serviceStr, serviceNameStr)
216
+		}
217
+
218
+		return store.DeleteConfig(tx, request.ConfigID)
219
+	})
220
+	switch err {
221
+	case store.ErrNotExist:
222
+		return nil, grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
223
+	case nil:
224
+		log.G(ctx).WithFields(logrus.Fields{
225
+			"config.ID": request.ConfigID,
226
+			"method":    "RemoveConfig",
227
+		}).Debugf("config removed")
228
+
229
+		return &api.RemoveConfigResponse{}, nil
230
+	default:
231
+		return nil, err
232
+	}
233
+}
234
+
235
+func validateConfigSpec(spec *api.ConfigSpec) error {
236
+	if spec == nil {
237
+		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
238
+	}
239
+	if err := validateConfigOrSecretAnnotations(spec.Annotations); err != nil {
240
+		return err
241
+	}
242
+
243
+	if len(spec.Data) >= MaxConfigSize || len(spec.Data) < 1 {
244
+		return grpc.Errorf(codes.InvalidArgument, "config data must be larger than 0 and less than %d bytes", MaxConfigSize)
245
+	}
246
+	return nil
247
+}
... ...
@@ -2,7 +2,6 @@ package controlapi
2 2
 
3 3
 import (
4 4
 	"crypto/subtle"
5
-	"regexp"
6 5
 	"strings"
7 6
 
8 7
 	"github.com/Sirupsen/logrus"
... ...
@@ -15,13 +14,9 @@ import (
15 15
 	"google.golang.org/grpc/codes"
16 16
 )
17 17
 
18
-// Currently this is contains the unimplemented secret functions in order to satisfy the interface
19
-
20 18
 // MaxSecretSize is the maximum byte length of the `Secret.Spec.Data` field.
21 19
 const MaxSecretSize = 500 * 1024 // 500KB
22 20
 
23
-var validSecretNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9]+(?:[a-zA-Z0-9-_.]*[a-zA-Z0-9])?$`)
24
-
25 21
 // assumes spec is not nil
26 22
 func secretFromSecretSpec(spec *api.SecretSpec) *api.Secret {
27 23
 	return &api.Secret{
... ...
@@ -247,7 +242,7 @@ func validateSecretSpec(spec *api.SecretSpec) error {
247 247
 	if spec == nil {
248 248
 		return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
249 249
 	}
250
-	if err := validateSecretAnnotations(spec.Annotations); err != nil {
250
+	if err := validateConfigOrSecretAnnotations(spec.Annotations); err != nil {
251 251
 		return err
252 252
 	}
253 253
 
... ...
@@ -256,14 +251,3 @@ func validateSecretSpec(spec *api.SecretSpec) error {
256 256
 	}
257 257
 	return nil
258 258
 }
259
-
260
-func validateSecretAnnotations(m api.Annotations) error {
261
-	if m.Name == "" {
262
-		return grpc.Errorf(codes.InvalidArgument, "name must be provided")
263
-	} else if len(m.Name) > 64 || !validSecretNameRegexp.MatchString(m.Name) {
264
-		// if the name doesn't match the regex
265
-		return grpc.Errorf(codes.InvalidArgument,
266
-			"invalid name, only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]")
267
-	}
268
-	return nil
269
-}
... ...
@@ -206,11 +206,16 @@ func validateTaskSpec(taskSpec api.TaskSpec) error {
206 206
 		return err
207 207
 	}
208 208
 
209
-	// Check to see if the Secret Reference portion of the spec is valid
209
+	// Check to see if the secret reference portion of the spec is valid
210 210
 	if err := validateSecretRefsSpec(taskSpec); err != nil {
211 211
 		return err
212 212
 	}
213 213
 
214
+	// Check to see if the config reference portion of the spec is valid
215
+	if err := validateConfigRefsSpec(taskSpec); err != nil {
216
+		return err
217
+	}
218
+
214 219
 	if taskSpec.GetRuntime() == nil {
215 220
 		return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
216 221
 	}
... ...
@@ -314,6 +319,48 @@ func validateSecretRefsSpec(spec api.TaskSpec) error {
314 314
 	return nil
315 315
 }
316 316
 
317
+// validateConfigRefsSpec finds if the configs passed in spec are valid and have no
318
+// conflicting targets.
319
+func validateConfigRefsSpec(spec api.TaskSpec) error {
320
+	container := spec.GetContainer()
321
+	if container == nil {
322
+		return nil
323
+	}
324
+
325
+	// Keep a map to track all the targets that will be exposed
326
+	// The string returned is only used for logging. It could as well be struct{}{}
327
+	existingTargets := make(map[string]string)
328
+	for _, configRef := range container.Configs {
329
+		// ConfigID and ConfigName are mandatory, we have invalid references without them
330
+		if configRef.ConfigID == "" || configRef.ConfigName == "" {
331
+			return grpc.Errorf(codes.InvalidArgument, "malformed config reference")
332
+		}
333
+
334
+		// Every config reference requires a Target
335
+		if configRef.GetTarget() == nil {
336
+			return grpc.Errorf(codes.InvalidArgument, "malformed config reference, no target provided")
337
+		}
338
+
339
+		// If this is a file target, we will ensure filename uniqueness
340
+		if configRef.GetFile() != nil {
341
+			fileName := configRef.GetFile().Name
342
+			// Validate the file name
343
+			if fileName == "" {
344
+				return grpc.Errorf(codes.InvalidArgument, "malformed file config reference, invalid target file name provided")
345
+			}
346
+
347
+			// If this target is already in use, we have conflicting targets
348
+			if prevConfigName, ok := existingTargets[fileName]; ok {
349
+				return grpc.Errorf(codes.InvalidArgument, "config references '%s' and '%s' have a conflicting target: '%s'", prevConfigName, configRef.ConfigName, fileName)
350
+			}
351
+
352
+			existingTargets[fileName] = configRef.ConfigName
353
+		}
354
+	}
355
+
356
+	return nil
357
+}
358
+
317 359
 func (s *Server) validateNetworks(networks []*api.NetworkAttachmentConfig) error {
318 360
 	for _, na := range networks {
319 361
 		var network *api.Network
... ...
@@ -459,6 +506,35 @@ func (s *Server) checkSecretExistence(tx store.Tx, spec *api.ServiceSpec) error
459 459
 	return nil
460 460
 }
461 461
 
462
+// checkConfigExistence finds if the config exists
463
+func (s *Server) checkConfigExistence(tx store.Tx, spec *api.ServiceSpec) error {
464
+	container := spec.Task.GetContainer()
465
+	if container == nil {
466
+		return nil
467
+	}
468
+
469
+	var failedConfigs []string
470
+	for _, configRef := range container.Configs {
471
+		config := store.GetConfig(tx, configRef.ConfigID)
472
+		// Check to see if the config exists and configRef.ConfigName matches the actual configName
473
+		if config == nil || config.Spec.Annotations.Name != configRef.ConfigName {
474
+			failedConfigs = append(failedConfigs, configRef.ConfigName)
475
+		}
476
+	}
477
+
478
+	if len(failedConfigs) > 0 {
479
+		configStr := "configs"
480
+		if len(failedConfigs) == 1 {
481
+			configStr = "config"
482
+		}
483
+
484
+		return grpc.Errorf(codes.InvalidArgument, "%s not found: %v", configStr, strings.Join(failedConfigs, ", "))
485
+
486
+	}
487
+
488
+	return nil
489
+}
490
+
462 491
 // CreateService creates and returns a Service based on the provided ServiceSpec.
463 492
 // - Returns `InvalidArgument` if the ServiceSpec is malformed.
464 493
 // - Returns `Unimplemented` if the ServiceSpec references unimplemented features.
... ...
@@ -498,6 +574,10 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe
498 498
 		if err != nil {
499 499
 			return err
500 500
 		}
501
+		err = s.checkConfigExistence(tx, request.Spec)
502
+		if err != nil {
503
+			return err
504
+		}
501 505
 
502 506
 		return store.CreateService(tx, service)
503 507
 	})
... ...
@@ -585,6 +665,11 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
585 585
 			return err
586 586
 		}
587 587
 
588
+		err = s.checkConfigExistence(tx, request.Spec)
589
+		if err != nil {
590
+			return err
591
+		}
592
+
588 593
 		// orchestrator is designed to be stateless, so it should not deal
589 594
 		// with service mode change (comparing current config with previous config).
590 595
 		// proper way to change service mode is to delete and re-add.
... ...
@@ -621,7 +706,7 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
621 621
 			service.Spec = *request.Spec.Copy()
622 622
 			// Set spec version. Note that this will not match the
623 623
 			// service's Meta.Version after the store update. The
624
-			// versionsfor the spec and the service itself are not
624
+			// versions for the spec and the service itself are not
625 625
 			// meant to be directly comparable.
626 626
 			service.SpecVersion = service.Meta.Version.Copy()
627 627
 
628 628
new file mode 100644
... ...
@@ -0,0 +1,247 @@
0
+package dispatcher
1
+
2
+import (
3
+	"github.com/Sirupsen/logrus"
4
+	"github.com/docker/swarmkit/api"
5
+	"github.com/docker/swarmkit/api/equality"
6
+	"github.com/docker/swarmkit/manager/state/store"
7
+)
8
+
9
+// Used as a key in tasksUsingDependency and changes. Only using the
10
+// ID could cause (rare) collisions between different types of
11
+// objects, so we also include the type of object in the key.
12
+type objectType int
13
+
14
+const (
15
+	typeTask objectType = iota
16
+	typeSecret
17
+	typeConfig
18
+)
19
+
20
+type typeAndID struct {
21
+	id      string
22
+	objType objectType
23
+}
24
+
25
+type assignmentSet struct {
26
+	tasksMap             map[string]*api.Task
27
+	tasksUsingDependency map[typeAndID]map[string]struct{}
28
+	changes              map[typeAndID]*api.AssignmentChange
29
+
30
+	log *logrus.Entry
31
+}
32
+
33
+func newAssignmentSet(log *logrus.Entry) *assignmentSet {
34
+	return &assignmentSet{
35
+		changes:              make(map[typeAndID]*api.AssignmentChange),
36
+		tasksMap:             make(map[string]*api.Task),
37
+		tasksUsingDependency: make(map[typeAndID]map[string]struct{}),
38
+		log:                  log,
39
+	}
40
+}
41
+
42
+func (a *assignmentSet) addTaskDependencies(readTx store.ReadTx, t *api.Task) {
43
+	var secrets []*api.SecretReference
44
+	container := t.Spec.GetContainer()
45
+	if container != nil {
46
+		secrets = container.Secrets
47
+	}
48
+	for _, secretRef := range secrets {
49
+		secretID := secretRef.SecretID
50
+		mapKey := typeAndID{objType: typeSecret, id: secretID}
51
+
52
+		if len(a.tasksUsingDependency[mapKey]) == 0 {
53
+			a.tasksUsingDependency[mapKey] = make(map[string]struct{})
54
+
55
+			secret := store.GetSecret(readTx, secretID)
56
+			if secret == nil {
57
+				a.log.WithFields(logrus.Fields{
58
+					"secret.id":   secretID,
59
+					"secret.name": secretRef.SecretName,
60
+				}).Debug("secret not found")
61
+				continue
62
+			}
63
+
64
+			// If the secret was found, add this secret to
65
+			// our set that we send down.
66
+			a.changes[mapKey] = &api.AssignmentChange{
67
+				Assignment: &api.Assignment{
68
+					Item: &api.Assignment_Secret{
69
+						Secret: secret,
70
+					},
71
+				},
72
+				Action: api.AssignmentChange_AssignmentActionUpdate,
73
+			}
74
+		}
75
+		a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
76
+	}
77
+
78
+	var configs []*api.ConfigReference
79
+	if container != nil {
80
+		configs = container.Configs
81
+	}
82
+	for _, configRef := range configs {
83
+		configID := configRef.ConfigID
84
+		mapKey := typeAndID{objType: typeConfig, id: configID}
85
+
86
+		if len(a.tasksUsingDependency[mapKey]) == 0 {
87
+			a.tasksUsingDependency[mapKey] = make(map[string]struct{})
88
+
89
+			config := store.GetConfig(readTx, configID)
90
+			if config == nil {
91
+				a.log.WithFields(logrus.Fields{
92
+					"config.id":   configID,
93
+					"config.name": configRef.ConfigName,
94
+				}).Debug("config not found")
95
+				continue
96
+			}
97
+
98
+			// If the config was found, add this config to
99
+			// our set that we send down.
100
+			a.changes[mapKey] = &api.AssignmentChange{
101
+				Assignment: &api.Assignment{
102
+					Item: &api.Assignment_Config{
103
+						Config: config,
104
+					},
105
+				},
106
+				Action: api.AssignmentChange_AssignmentActionUpdate,
107
+			}
108
+		}
109
+		a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
110
+	}
111
+}
112
+
113
+func (a *assignmentSet) releaseDependency(mapKey typeAndID, assignment *api.Assignment, taskID string) bool {
114
+	delete(a.tasksUsingDependency[mapKey], taskID)
115
+	if len(a.tasksUsingDependency[mapKey]) != 0 {
116
+		return false
117
+	}
118
+	// No tasks are using the dependency anymore
119
+	delete(a.tasksUsingDependency, mapKey)
120
+	a.changes[mapKey] = &api.AssignmentChange{
121
+		Assignment: assignment,
122
+		Action:     api.AssignmentChange_AssignmentActionRemove,
123
+	}
124
+	return true
125
+}
126
+
127
+func (a *assignmentSet) releaseTaskDependencies(t *api.Task) bool {
128
+	var modified bool
129
+	container := t.Spec.GetContainer()
130
+
131
+	var secrets []*api.SecretReference
132
+	if container != nil {
133
+		secrets = container.Secrets
134
+	}
135
+
136
+	for _, secretRef := range secrets {
137
+		secretID := secretRef.SecretID
138
+		mapKey := typeAndID{objType: typeSecret, id: secretID}
139
+		assignment := &api.Assignment{
140
+			Item: &api.Assignment_Secret{
141
+				Secret: &api.Secret{ID: secretID},
142
+			},
143
+		}
144
+		if a.releaseDependency(mapKey, assignment, t.ID) {
145
+			modified = true
146
+		}
147
+	}
148
+
149
+	var configs []*api.ConfigReference
150
+	if container != nil {
151
+		configs = container.Configs
152
+	}
153
+
154
+	for _, configRef := range configs {
155
+		configID := configRef.ConfigID
156
+		mapKey := typeAndID{objType: typeConfig, id: configID}
157
+		assignment := &api.Assignment{
158
+			Item: &api.Assignment_Config{
159
+				Config: &api.Config{ID: configID},
160
+			},
161
+		}
162
+		if a.releaseDependency(mapKey, assignment, t.ID) {
163
+			modified = true
164
+		}
165
+	}
166
+
167
+	return modified
168
+}
169
+
170
+func (a *assignmentSet) addOrUpdateTask(readTx store.ReadTx, t *api.Task) bool {
171
+	// We only care about tasks that are ASSIGNED or higher.
172
+	if t.Status.State < api.TaskStateAssigned {
173
+		return false
174
+	}
175
+
176
+	if oldTask, exists := a.tasksMap[t.ID]; exists {
177
+		// States ASSIGNED and below are set by the orchestrator/scheduler,
178
+		// not the agent, so tasks in these states need to be sent to the
179
+		// agent even if nothing else has changed.
180
+		if equality.TasksEqualStable(oldTask, t) && t.Status.State > api.TaskStateAssigned {
181
+			// this update should not trigger a task change for the agent
182
+			a.tasksMap[t.ID] = t
183
+			// If this task got updated to a final state, let's release
184
+			// the dependencies that are being used by the task
185
+			if t.Status.State > api.TaskStateRunning {
186
+				// If releasing the dependencies caused us to
187
+				// remove something from the assignment set,
188
+				// mark one modification.
189
+				return a.releaseTaskDependencies(t)
190
+			}
191
+			return false
192
+		}
193
+	} else if t.Status.State <= api.TaskStateRunning {
194
+		// If this task wasn't part of the assignment set before, and it's <= RUNNING
195
+		// add the dependencies it references to the assignment.
196
+		// Task states > RUNNING are worker reported only, are never created in
197
+		// a > RUNNING state.
198
+		a.addTaskDependencies(readTx, t)
199
+	}
200
+	a.tasksMap[t.ID] = t
201
+	a.changes[typeAndID{objType: typeTask, id: t.ID}] = &api.AssignmentChange{
202
+		Assignment: &api.Assignment{
203
+			Item: &api.Assignment_Task{
204
+				Task: t,
205
+			},
206
+		},
207
+		Action: api.AssignmentChange_AssignmentActionUpdate,
208
+	}
209
+	return true
210
+}
211
+
212
+func (a *assignmentSet) removeTask(t *api.Task) bool {
213
+	if _, exists := a.tasksMap[t.ID]; !exists {
214
+		return false
215
+	}
216
+
217
+	a.changes[typeAndID{objType: typeTask, id: t.ID}] = &api.AssignmentChange{
218
+		Assignment: &api.Assignment{
219
+			Item: &api.Assignment_Task{
220
+				Task: &api.Task{ID: t.ID},
221
+			},
222
+		},
223
+		Action: api.AssignmentChange_AssignmentActionRemove,
224
+	}
225
+
226
+	delete(a.tasksMap, t.ID)
227
+
228
+	// Release the dependencies being used by this task.
229
+	// Ignoring the return here. We will always mark this as a
230
+	// modification, since a task is being removed.
231
+	a.releaseTaskDependencies(t)
232
+	return true
233
+}
234
+
235
+func (a *assignmentSet) message() api.AssignmentsMessage {
236
+	var message api.AssignmentsMessage
237
+	for _, change := range a.changes {
238
+		message.Changes = append(message.Changes, change)
239
+	}
240
+
241
+	// The the set of changes is reinitialized to prepare for formation
242
+	// of the next message.
243
+	a.changes = make(map[typeAndID]*api.AssignmentChange)
244
+
245
+	return message
246
+}
... ...
@@ -102,20 +102,29 @@ type nodeUpdate struct {
102 102
 	description *api.NodeDescription
103 103
 }
104 104
 
105
+// clusterUpdate is an object that stores an update to the cluster that should trigger
106
+// a new session message.  These are pointers to indicate the difference between
107
+// "there is no update" and "update this to nil"
108
+type clusterUpdate struct {
109
+	managerUpdate      *[]*api.WeightedPeer
110
+	bootstrapKeyUpdate *[]*api.EncryptionKey
111
+	rootCAUpdate       *[]byte
112
+}
113
+
105 114
 // Dispatcher is responsible for dispatching tasks and tracking agent health.
106 115
 type Dispatcher struct {
107 116
 	mu                   sync.Mutex
108 117
 	wg                   sync.WaitGroup
109 118
 	nodes                *nodeStore
110 119
 	store                *store.MemoryStore
111
-	mgrQueue             *watch.Queue
112 120
 	lastSeenManagers     []*api.WeightedPeer
113 121
 	networkBootstrapKeys []*api.EncryptionKey
114
-	keyMgrQueue          *watch.Queue
122
+	lastSeenRootCert     []byte
115 123
 	config               *Config
116 124
 	cluster              Cluster
117 125
 	ctx                  context.Context
118 126
 	cancel               context.CancelFunc
127
+	clusterUpdateQueue   *watch.Queue
119 128
 
120 129
 	taskUpdates     map[string]*api.TaskStatus // indexed by task ID
121 130
 	taskUpdatesLock sync.Mutex
... ...
@@ -196,6 +205,7 @@ func (d *Dispatcher) Run(ctx context.Context) error {
196 196
 				if clusters[0].NetworkBootstrapKeys != nil {
197 197
 					d.networkBootstrapKeys = clusters[0].NetworkBootstrapKeys
198 198
 				}
199
+				d.lastSeenRootCert = clusters[0].RootCA.CACert
199 200
 			}
200 201
 			return nil
201 202
 		},
... ...
@@ -205,9 +215,8 @@ func (d *Dispatcher) Run(ctx context.Context) error {
205 205
 		d.mu.Unlock()
206 206
 		return err
207 207
 	}
208
-	// set queues here to guarantee that Close will close them
209
-	d.mgrQueue = watch.NewQueue()
210
-	d.keyMgrQueue = watch.NewQueue()
208
+	// set queue here to guarantee that Close will close it
209
+	d.clusterUpdateQueue = watch.NewQueue()
211 210
 
212 211
 	peerWatcher, peerCancel := d.cluster.SubscribePeers()
213 212
 	defer peerCancel()
... ...
@@ -231,7 +240,7 @@ func (d *Dispatcher) Run(ctx context.Context) error {
231 231
 		d.mu.Lock()
232 232
 		d.lastSeenManagers = mgrs
233 233
 		d.mu.Unlock()
234
-		d.mgrQueue.Publish(mgrs)
234
+		d.clusterUpdateQueue.Publish(clusterUpdate{managerUpdate: &mgrs})
235 235
 	}
236 236
 
237 237
 	batchTimer := time.NewTimer(maxBatchInterval)
... ...
@@ -259,9 +268,13 @@ func (d *Dispatcher) Run(ctx context.Context) error {
259 259
 					d.nodes.updatePeriod(d.config.HeartbeatPeriod, d.config.HeartbeatEpsilon, d.config.GracePeriodMultiplier)
260 260
 				}
261 261
 			}
262
+			d.lastSeenRootCert = cluster.Cluster.RootCA.CACert
262 263
 			d.networkBootstrapKeys = cluster.Cluster.NetworkBootstrapKeys
263 264
 			d.mu.Unlock()
264
-			d.keyMgrQueue.Publish(cluster.Cluster.NetworkBootstrapKeys)
265
+			d.clusterUpdateQueue.Publish(clusterUpdate{
266
+				bootstrapKeyUpdate: &cluster.Cluster.NetworkBootstrapKeys,
267
+				rootCAUpdate:       &cluster.Cluster.RootCA.CACert,
268
+			})
265 269
 		case <-ctx.Done():
266 270
 			return nil
267 271
 		}
... ...
@@ -286,8 +299,7 @@ func (d *Dispatcher) Stop() error {
286 286
 	d.processUpdatesCond.Broadcast()
287 287
 	d.processUpdatesLock.Unlock()
288 288
 
289
-	d.mgrQueue.Close()
290
-	d.keyMgrQueue.Close()
289
+	d.clusterUpdateQueue.Close()
291 290
 
292 291
 	d.wg.Wait()
293 292
 
... ...
@@ -812,12 +824,10 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
812 812
 	}
813 813
 
814 814
 	var (
815
-		sequence  int64
816
-		appliesTo string
817
-		initial   api.AssignmentsMessage
815
+		sequence    int64
816
+		appliesTo   string
817
+		assignments = newAssignmentSet(log)
818 818
 	)
819
-	tasksMap := make(map[string]*api.Task)
820
-	tasksUsingSecret := make(map[string]map[string]struct{})
821 819
 
822 820
 	sendMessage := func(msg api.AssignmentsMessage, assignmentType api.AssignmentsMessage_Type) error {
823 821
 		sequence++
... ...
@@ -832,39 +842,6 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
832 832
 		return nil
833 833
 	}
834 834
 
835
-	// returns a slice of new secrets to send down
836
-	addSecretsForTask := func(readTx store.ReadTx, t *api.Task) []*api.Secret {
837
-		container := t.Spec.GetContainer()
838
-		if container == nil {
839
-			return nil
840
-		}
841
-		var newSecrets []*api.Secret
842
-		for _, secretRef := range container.Secrets {
843
-			secretID := secretRef.SecretID
844
-			log := log.WithFields(logrus.Fields{
845
-				"secret.id":   secretID,
846
-				"secret.name": secretRef.SecretName,
847
-			})
848
-
849
-			if len(tasksUsingSecret[secretID]) == 0 {
850
-				tasksUsingSecret[secretID] = make(map[string]struct{})
851
-
852
-				secret := store.GetSecret(readTx, secretID)
853
-				if secret == nil {
854
-					log.Debug("secret not found")
855
-					continue
856
-				}
857
-
858
-				// If the secret was found, add this secret to
859
-				// our set that we send down.
860
-				newSecrets = append(newSecrets, secret)
861
-			}
862
-			tasksUsingSecret[secretID][t.ID] = struct{}{}
863
-		}
864
-
865
-		return newSecrets
866
-	}
867
-
868 835
 	// TODO(aaronl): Also send node secrets that should be exposed to
869 836
 	// this node.
870 837
 	nodeTasks, cancel, err := store.ViewAndWatch(
... ...
@@ -876,57 +853,22 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
876 876
 			}
877 877
 
878 878
 			for _, t := range tasks {
879
-				// We only care about tasks that are ASSIGNED or
880
-				// higher. If the state is below ASSIGNED, the
881
-				// task may not meet the constraints for this
882
-				// node, so we have to be careful about sending
883
-				// secrets associated with it.
884
-				if t.Status.State < api.TaskStateAssigned {
885
-					continue
886
-				}
887
-
888
-				tasksMap[t.ID] = t
889
-				taskChange := &api.AssignmentChange{
890
-					Assignment: &api.Assignment{
891
-						Item: &api.Assignment_Task{
892
-							Task: t,
893
-						},
894
-					},
895
-					Action: api.AssignmentChange_AssignmentActionUpdate,
896
-				}
897
-				initial.Changes = append(initial.Changes, taskChange)
898
-				// Only send secrets down if these tasks are in < RUNNING
899
-				if t.Status.State <= api.TaskStateRunning {
900
-					newSecrets := addSecretsForTask(readTx, t)
901
-					for _, secret := range newSecrets {
902
-						secretChange := &api.AssignmentChange{
903
-							Assignment: &api.Assignment{
904
-								Item: &api.Assignment_Secret{
905
-									Secret: secret,
906
-								},
907
-							},
908
-							Action: api.AssignmentChange_AssignmentActionUpdate,
909
-						}
910
-
911
-						initial.Changes = append(initial.Changes, secretChange)
912
-					}
913
-				}
879
+				assignments.addOrUpdateTask(readTx, t)
914 880
 			}
881
+
915 882
 			return nil
916 883
 		},
917 884
 		api.EventUpdateTask{Task: &api.Task{NodeID: nodeID},
918 885
 			Checks: []api.TaskCheckFunc{api.TaskCheckNodeID}},
919 886
 		api.EventDeleteTask{Task: &api.Task{NodeID: nodeID},
920 887
 			Checks: []api.TaskCheckFunc{api.TaskCheckNodeID}},
921
-		api.EventUpdateSecret{},
922
-		api.EventDeleteSecret{},
923 888
 	)
924 889
 	if err != nil {
925 890
 		return err
926 891
 	}
927 892
 	defer cancel()
928 893
 
929
-	if err := sendMessage(initial, api.AssignmentsMessage_COMPLETE); err != nil {
894
+	if err := sendMessage(assignments.message(), api.AssignmentsMessage_COMPLETE); err != nil {
930 895
 		return err
931 896
 	}
932 897
 
... ...
@@ -938,14 +880,9 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
938 938
 
939 939
 		// bursty events should be processed in batches and sent out together
940 940
 		var (
941
-			update          api.AssignmentsMessage
942 941
 			modificationCnt int
943 942
 			batchingTimer   *time.Timer
944 943
 			batchingTimeout <-chan time.Time
945
-			updateTasks     = make(map[string]*api.Task)
946
-			updateSecrets   = make(map[string]*api.Secret)
947
-			removeTasks     = make(map[string]struct{})
948
-			removeSecrets   = make(map[string]struct{})
949 944
 		)
950 945
 
951 946
 		oneModification := func() {
... ...
@@ -959,28 +896,6 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
959 959
 			}
960 960
 		}
961 961
 
962
-		// Release the secrets references from this task
963
-		releaseSecretsForTask := func(t *api.Task) bool {
964
-			var modified bool
965
-			container := t.Spec.GetContainer()
966
-			if container == nil {
967
-				return modified
968
-			}
969
-
970
-			for _, secretRef := range container.Secrets {
971
-				secretID := secretRef.SecretID
972
-				delete(tasksUsingSecret[secretID], t.ID)
973
-				if len(tasksUsingSecret[secretID]) == 0 {
974
-					// No tasks are using the secret anymore
975
-					delete(tasksUsingSecret, secretID)
976
-					removeSecrets[secretID] = struct{}{}
977
-					modified = true
978
-				}
979
-			}
980
-
981
-			return modified
982
-		}
983
-
984 962
 		// The batching loop waits for 50 ms after the most recent
985 963
 		// change, or until modificationBatchLimit is reached. The
986 964
 		// worst case latency is modificationBatchLimit * batchingWaitTime,
... ...
@@ -996,78 +911,17 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
996 996
 				// them to ASSIGNED. If this ever changes, we will need
997 997
 				// to monitor task creations as well.
998 998
 				case api.EventUpdateTask:
999
-					// We only care about tasks that are ASSIGNED or
1000
-					// higher.
1001
-					if v.Task.Status.State < api.TaskStateAssigned {
1002
-						continue
1003
-					}
1004
-
1005
-					if oldTask, exists := tasksMap[v.Task.ID]; exists {
1006
-						// States ASSIGNED and below are set by the orchestrator/scheduler,
1007
-						// not the agent, so tasks in these states need to be sent to the
1008
-						// agent even if nothing else has changed.
1009
-						if equality.TasksEqualStable(oldTask, v.Task) && v.Task.Status.State > api.TaskStateAssigned {
1010
-							// this update should not trigger a task change for the agent
1011
-							tasksMap[v.Task.ID] = v.Task
1012
-							// If this task got updated to a final state, let's release
1013
-							// the secrets that are being used by the task
1014
-							if v.Task.Status.State > api.TaskStateRunning {
1015
-								// If releasing the secrets caused a secret to be
1016
-								// removed from an agent, mark one modification
1017
-								if releaseSecretsForTask(v.Task) {
1018
-									oneModification()
1019
-								}
1020
-							}
1021
-							continue
1022
-						}
1023
-					} else if v.Task.Status.State <= api.TaskStateRunning {
1024
-						// If this task wasn't part of the assignment set before, and it's <= RUNNING
1025
-						// add the secrets it references to the secrets assignment.
1026
-						// Task states > RUNNING are worker reported only, are never created in
1027
-						// a > RUNNING state.
1028
-						var newSecrets []*api.Secret
1029
-						d.store.View(func(readTx store.ReadTx) {
1030
-							newSecrets = addSecretsForTask(readTx, v.Task)
1031
-						})
1032
-						for _, secret := range newSecrets {
1033
-							updateSecrets[secret.ID] = secret
999
+					d.store.View(func(readTx store.ReadTx) {
1000
+						if assignments.addOrUpdateTask(readTx, v.Task) {
1001
+							oneModification()
1034 1002
 						}
1035
-					}
1036
-					tasksMap[v.Task.ID] = v.Task
1037
-					updateTasks[v.Task.ID] = v.Task
1038
-
1039
-					oneModification()
1003
+					})
1040 1004
 				case api.EventDeleteTask:
1041
-					if _, exists := tasksMap[v.Task.ID]; !exists {
1042
-						continue
1005
+					if assignments.removeTask(v.Task) {
1006
+						oneModification()
1043 1007
 					}
1044
-
1045
-					removeTasks[v.Task.ID] = struct{}{}
1046
-
1047
-					delete(tasksMap, v.Task.ID)
1048
-
1049
-					// Release the secrets being used by this task
1050
-					// Ignoring the return here. We will always mark
1051
-					// this as a modification, since a task is being
1052
-					// removed.
1053
-					releaseSecretsForTask(v.Task)
1054
-
1055
-					oneModification()
1056
-				// TODO(aaronl): For node secrets, we'll need to handle
1057
-				// EventCreateSecret.
1058
-				case api.EventUpdateSecret:
1059
-					if _, exists := tasksUsingSecret[v.Secret.ID]; !exists {
1060
-						continue
1061
-					}
1062
-					log.Debugf("Secret %s (ID: %d) was updated though it was still referenced by one or more tasks",
1063
-						v.Secret.Spec.Annotations.Name, v.Secret.ID)
1064
-
1065
-				case api.EventDeleteSecret:
1066
-					if _, exists := tasksUsingSecret[v.Secret.ID]; !exists {
1067
-						continue
1068
-					}
1069
-					log.Debugf("Secret %s (ID: %d) was deleted though it was still referenced by one or more tasks",
1070
-						v.Secret.Spec.Annotations.Name, v.Secret.ID)
1008
+					// TODO(aaronl): For node secrets, we'll need to handle
1009
+					// EventCreateSecret.
1071 1010
 				}
1072 1011
 			case <-batchingTimeout:
1073 1012
 				break batchingLoop
... ...
@@ -1083,72 +937,7 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
1083 1083
 		}
1084 1084
 
1085 1085
 		if modificationCnt > 0 {
1086
-			for id, task := range updateTasks {
1087
-				if _, ok := removeTasks[id]; !ok {
1088
-					taskChange := &api.AssignmentChange{
1089
-						Assignment: &api.Assignment{
1090
-							Item: &api.Assignment_Task{
1091
-								Task: task,
1092
-							},
1093
-						},
1094
-						Action: api.AssignmentChange_AssignmentActionUpdate,
1095
-					}
1096
-
1097
-					update.Changes = append(update.Changes, taskChange)
1098
-				}
1099
-			}
1100
-			for id, secret := range updateSecrets {
1101
-				// If, due to multiple updates, this secret is no longer in use,
1102
-				// don't send it down.
1103
-				if len(tasksUsingSecret[id]) == 0 {
1104
-					// delete this secret for the secrets to be updated
1105
-					// so that deleteSecrets knows the current list
1106
-					delete(updateSecrets, id)
1107
-					continue
1108
-				}
1109
-				secretChange := &api.AssignmentChange{
1110
-					Assignment: &api.Assignment{
1111
-						Item: &api.Assignment_Secret{
1112
-							Secret: secret,
1113
-						},
1114
-					},
1115
-					Action: api.AssignmentChange_AssignmentActionUpdate,
1116
-				}
1117
-
1118
-				update.Changes = append(update.Changes, secretChange)
1119
-			}
1120
-			for id := range removeTasks {
1121
-				taskChange := &api.AssignmentChange{
1122
-					Assignment: &api.Assignment{
1123
-						Item: &api.Assignment_Task{
1124
-							Task: &api.Task{ID: id},
1125
-						},
1126
-					},
1127
-					Action: api.AssignmentChange_AssignmentActionRemove,
1128
-				}
1129
-
1130
-				update.Changes = append(update.Changes, taskChange)
1131
-			}
1132
-			for id := range removeSecrets {
1133
-				// If this secret is also being sent on the updated set
1134
-				// don't also add it to the removed set
1135
-				if _, ok := updateSecrets[id]; ok {
1136
-					continue
1137
-				}
1138
-
1139
-				secretChange := &api.AssignmentChange{
1140
-					Assignment: &api.Assignment{
1141
-						Item: &api.Assignment_Secret{
1142
-							Secret: &api.Secret{ID: id},
1143
-						},
1144
-					},
1145
-					Action: api.AssignmentChange_AssignmentActionRemove,
1146
-				}
1147
-
1148
-				update.Changes = append(update.Changes, secretChange)
1149
-			}
1150
-
1151
-			if err := sendMessage(update, api.AssignmentsMessage_INCREMENTAL); err != nil {
1086
+			if err := sendMessage(assignments.message(), api.AssignmentsMessage_INCREMENTAL); err != nil {
1152 1087
 				return err
1153 1088
 			}
1154 1089
 		}
... ...
@@ -1284,6 +1073,12 @@ func (d *Dispatcher) getNetworkBootstrapKeys() []*api.EncryptionKey {
1284 1284
 	return d.networkBootstrapKeys
1285 1285
 }
1286 1286
 
1287
+func (d *Dispatcher) getRootCACert() []byte {
1288
+	d.mu.Lock()
1289
+	defer d.mu.Unlock()
1290
+	return d.lastSeenRootCert
1291
+}
1292
+
1287 1293
 // Session is a stream which controls agent connection.
1288 1294
 // Each message contains list of backup Managers with weights. Also there is
1289 1295
 // a special boolean field Disconnect which if true indicates that node should
... ...
@@ -1355,14 +1150,13 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
1355 1355
 		Node:                 nodeObj,
1356 1356
 		Managers:             d.getManagers(),
1357 1357
 		NetworkBootstrapKeys: d.getNetworkBootstrapKeys(),
1358
+		RootCA:               d.getRootCACert(),
1358 1359
 	}); err != nil {
1359 1360
 		return err
1360 1361
 	}
1361 1362
 
1362
-	managerUpdates, mgrCancel := d.mgrQueue.Watch()
1363
-	defer mgrCancel()
1364
-	keyMgrUpdates, keyMgrCancel := d.keyMgrQueue.Watch()
1365
-	defer keyMgrCancel()
1363
+	clusterUpdatesCh, clusterCancel := d.clusterUpdateQueue.Watch()
1364
+	defer clusterCancel()
1366 1365
 
1367 1366
 	// disconnectNode is a helper forcibly shutdown connection
1368 1367
 	disconnectNode := func() error {
... ...
@@ -1396,11 +1190,21 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
1396 1396
 			disconnect bool
1397 1397
 			mgrs       []*api.WeightedPeer
1398 1398
 			netKeys    []*api.EncryptionKey
1399
+			rootCert   []byte
1399 1400
 		)
1400 1401
 
1401 1402
 		select {
1402
-		case ev := <-managerUpdates:
1403
-			mgrs = ev.([]*api.WeightedPeer)
1403
+		case ev := <-clusterUpdatesCh:
1404
+			update := ev.(clusterUpdate)
1405
+			if update.managerUpdate != nil {
1406
+				mgrs = *update.managerUpdate
1407
+			}
1408
+			if update.bootstrapKeyUpdate != nil {
1409
+				netKeys = *update.bootstrapKeyUpdate
1410
+			}
1411
+			if update.rootCAUpdate != nil {
1412
+				rootCert = *update.rootCAUpdate
1413
+			}
1404 1414
 		case ev := <-nodeUpdates:
1405 1415
 			nodeObj = ev.(api.EventUpdateNode).Node
1406 1416
 		case <-stream.Context().Done():
... ...
@@ -1409,8 +1213,6 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
1409 1409
 			disconnect = true
1410 1410
 		case <-dctx.Done():
1411 1411
 			disconnect = true
1412
-		case ev := <-keyMgrUpdates:
1413
-			netKeys = ev.([]*api.EncryptionKey)
1414 1412
 		}
1415 1413
 		if mgrs == nil {
1416 1414
 			mgrs = d.getManagers()
... ...
@@ -1418,12 +1220,16 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
1418 1418
 		if netKeys == nil {
1419 1419
 			netKeys = d.getNetworkBootstrapKeys()
1420 1420
 		}
1421
+		if rootCert == nil {
1422
+			rootCert = d.getRootCACert()
1423
+		}
1421 1424
 
1422 1425
 		if err := stream.Send(&api.SessionMessage{
1423 1426
 			SessionID:            sessionID,
1424 1427
 			Node:                 nodeObj,
1425 1428
 			Managers:             mgrs,
1426 1429
 			NetworkBootstrapKeys: netKeys,
1430
+			RootCA:               rootCert,
1427 1431
 		}); err != nil {
1428 1432
 			return err
1429 1433
 		}
... ...
@@ -65,6 +65,9 @@ type RemoteAddrs struct {
65 65
 type Config struct {
66 66
 	SecurityConfig *ca.SecurityConfig
67 67
 
68
+	// RootCAPaths is the path to which new root certs should be save
69
+	RootCAPaths ca.CertPaths
70
+
68 71
 	// ExternalCAs is a list of initial CAs to which a manager node
69 72
 	// will make certificate signing requests for node certificates.
70 73
 	ExternalCAs []*api.ExternalCA
... ...
@@ -210,7 +213,7 @@ func New(config *Config) (*Manager, error) {
210 210
 
211 211
 	m := &Manager{
212 212
 		config:          *config,
213
-		caserver:        ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig),
213
+		caserver:        ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig, config.RootCAPaths),
214 214
 		dispatcher:      dispatcher.New(raftNode, dispatcher.DefaultConfig()),
215 215
 		logbroker:       logbroker.New(raftNode.MemoryStore()),
216 216
 		server:          grpc.NewServer(opts...),
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"time"
6 6
 
7 7
 	"github.com/docker/swarmkit/api"
8
+	"github.com/docker/swarmkit/api/defaults"
8 9
 	"github.com/docker/swarmkit/identity"
9 10
 	"github.com/docker/swarmkit/protobuf/ptypes"
10 11
 )
... ...
@@ -50,7 +51,7 @@ func NewTask(cluster *api.Cluster, service *api.Service, slot uint64, nodeID str
50 50
 
51 51
 // RestartCondition returns the restart condition to apply to this task.
52 52
 func RestartCondition(task *api.Task) api.RestartPolicy_RestartCondition {
53
-	restartCondition := api.RestartOnAny
53
+	restartCondition := defaults.Service.Task.Restart.Condition
54 54
 	if task.Spec.Restart != nil {
55 55
 		restartCondition = task.Spec.Restart.Condition
56 56
 	}
... ...
@@ -155,31 +155,25 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
155 155
 		u.startUpdate(ctx, service.ID)
156 156
 	}
157 157
 
158
-	delay := defaults.Service.Update.Delay
159
-	parallelism := int(defaults.Service.Update.Parallelism)
160
-	failureAction := defaults.Service.Update.FailureAction
161
-	allowedFailureFraction := defaults.Service.Update.MaxFailureRatio
162
-	monitoringPeriod, _ := gogotypes.DurationFromProto(defaults.Service.Update.Monitor)
163
-	order := defaults.Service.Update.Order
158
+	var monitoringPeriod time.Duration
164 159
 
165 160
 	updateConfig := service.Spec.Update
166 161
 	if service.UpdateStatus != nil && service.UpdateStatus.State == api.UpdateStatus_ROLLBACK_STARTED {
162
+		monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Rollback.Monitor)
167 163
 		updateConfig = service.Spec.Rollback
164
+		if updateConfig == nil {
165
+			updateConfig = defaults.Service.Rollback
166
+		}
167
+	} else if updateConfig == nil {
168
+		monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Update.Monitor)
169
+		updateConfig = defaults.Service.Update
168 170
 	}
169 171
 
170
-	if updateConfig != nil {
171
-		failureAction = updateConfig.FailureAction
172
-		allowedFailureFraction = updateConfig.MaxFailureRatio
173
-		parallelism = int(updateConfig.Parallelism)
174
-		delay = updateConfig.Delay
175
-		order = updateConfig.Order
176
-
177
-		var err error
178
-		if updateConfig.Monitor != nil {
179
-			monitoringPeriod, err = gogotypes.DurationFromProto(updateConfig.Monitor)
180
-			if err != nil {
181
-				monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Update.Monitor)
182
-			}
172
+	parallelism := int(updateConfig.Parallelism)
173
+	if updateConfig.Monitor != nil {
174
+		newMonitoringPeriod, err := gogotypes.DurationFromProto(updateConfig.Monitor)
175
+		if err == nil {
176
+			monitoringPeriod = newMonitoringPeriod
183 177
 		}
184 178
 	}
185 179
 
... ...
@@ -195,14 +189,14 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
195 195
 	wg.Add(parallelism)
196 196
 	for i := 0; i < parallelism; i++ {
197 197
 		go func() {
198
-			u.worker(ctx, slotQueue, delay, order)
198
+			u.worker(ctx, slotQueue, updateConfig)
199 199
 			wg.Done()
200 200
 		}()
201 201
 	}
202 202
 
203 203
 	var failedTaskWatch chan events.Event
204 204
 
205
-	if failureAction != api.UpdateConfig_CONTINUE {
205
+	if updateConfig.FailureAction != api.UpdateConfig_CONTINUE {
206 206
 		var cancelWatch func()
207 207
 		failedTaskWatch, cancelWatch = state.Watch(
208 208
 			u.store.WatchQueue(),
... ...
@@ -234,8 +228,8 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
234 234
 		if found && (startedAt.IsZero() || time.Since(startedAt) <= monitoringPeriod) {
235 235
 			failedTasks[failedTask.ID] = struct{}{}
236 236
 			totalFailures++
237
-			if float32(totalFailures)/float32(len(dirtySlots)) > allowedFailureFraction {
238
-				switch failureAction {
237
+			if float32(totalFailures)/float32(len(dirtySlots)) > updateConfig.MaxFailureRatio {
238
+				switch updateConfig.FailureAction {
239 239
 				case api.UpdateConfig_PAUSE:
240 240
 					stopped = true
241 241
 					message := fmt.Sprintf("update paused due to failure or early termination of task %s", failedTask.ID)
... ...
@@ -309,7 +303,7 @@ slotsLoop:
309 309
 	}
310 310
 }
311 311
 
312
-func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot, delay time.Duration, order api.UpdateConfig_UpdateOrder) {
312
+func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot, updateConfig *api.UpdateConfig) {
313 313
 	for slot := range queue {
314 314
 		// Do we have a task with the new spec in desired state = RUNNING?
315 315
 		// If so, all we have to do to complete the update is remove the
... ...
@@ -346,14 +340,14 @@ func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot, de
346 346
 			}
347 347
 			updated.DesiredState = api.TaskStateReady
348 348
 
349
-			if err := u.updateTask(ctx, slot, updated, order); err != nil {
349
+			if err := u.updateTask(ctx, slot, updated, updateConfig.Order); err != nil {
350 350
 				log.G(ctx).WithError(err).WithField("task.id", updated.ID).Error("update failed")
351 351
 			}
352 352
 		}
353 353
 
354
-		if delay != 0 {
354
+		if updateConfig.Delay != 0 {
355 355
 			select {
356
-			case <-time.After(delay):
356
+			case <-time.After(updateConfig.Delay):
357 357
 			case <-u.stopChan:
358 358
 				return
359 359
 			}
... ...
@@ -154,6 +154,17 @@ func ByReferencedSecretID(secretID string) By {
154 154
 	return byReferencedSecretID(secretID)
155 155
 }
156 156
 
157
+type byReferencedConfigID string
158
+
159
+func (b byReferencedConfigID) isBy() {
160
+}
161
+
162
+// ByReferencedConfigID creates an object to pass to Find to search for a
163
+// service or task that references a config with the given ID.
164
+func ByReferencedConfigID(configID string) By {
165
+	return byReferencedConfigID(configID)
166
+}
167
+
157 168
 type byKind string
158 169
 
159 170
 func (b byKind) isBy() {
160 171
new file mode 100644
... ...
@@ -0,0 +1,132 @@
0
+package store
1
+
2
+import (
3
+	"strings"
4
+
5
+	"github.com/docker/swarmkit/api"
6
+	memdb "github.com/hashicorp/go-memdb"
7
+)
8
+
9
+const tableConfig = "config"
10
+
11
+func init() {
12
+	register(ObjectStoreConfig{
13
+		Table: &memdb.TableSchema{
14
+			Name: tableConfig,
15
+			Indexes: map[string]*memdb.IndexSchema{
16
+				indexID: {
17
+					Name:    indexID,
18
+					Unique:  true,
19
+					Indexer: api.ConfigIndexerByID{},
20
+				},
21
+				indexName: {
22
+					Name:    indexName,
23
+					Unique:  true,
24
+					Indexer: api.ConfigIndexerByName{},
25
+				},
26
+				indexCustom: {
27
+					Name:         indexCustom,
28
+					Indexer:      api.ConfigCustomIndexer{},
29
+					AllowMissing: true,
30
+				},
31
+			},
32
+		},
33
+		Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error {
34
+			var err error
35
+			snapshot.Configs, err = FindConfigs(tx, All)
36
+			return err
37
+		},
38
+		Restore: func(tx Tx, snapshot *api.StoreSnapshot) error {
39
+			configs, err := FindConfigs(tx, All)
40
+			if err != nil {
41
+				return err
42
+			}
43
+			for _, s := range configs {
44
+				if err := DeleteConfig(tx, s.ID); err != nil {
45
+					return err
46
+				}
47
+			}
48
+			for _, s := range snapshot.Configs {
49
+				if err := CreateConfig(tx, s); err != nil {
50
+					return err
51
+				}
52
+			}
53
+			return nil
54
+		},
55
+		ApplyStoreAction: func(tx Tx, sa api.StoreAction) error {
56
+			switch v := sa.Target.(type) {
57
+			case *api.StoreAction_Config:
58
+				obj := v.Config
59
+				switch sa.Action {
60
+				case api.StoreActionKindCreate:
61
+					return CreateConfig(tx, obj)
62
+				case api.StoreActionKindUpdate:
63
+					return UpdateConfig(tx, obj)
64
+				case api.StoreActionKindRemove:
65
+					return DeleteConfig(tx, obj.ID)
66
+				}
67
+			}
68
+			return errUnknownStoreAction
69
+		},
70
+	})
71
+}
72
+
73
+// CreateConfig adds a new config to the store.
74
+// Returns ErrExist if the ID is already taken.
75
+func CreateConfig(tx Tx, c *api.Config) error {
76
+	// Ensure the name is not already in use.
77
+	if tx.lookup(tableConfig, indexName, strings.ToLower(c.Spec.Annotations.Name)) != nil {
78
+		return ErrNameConflict
79
+	}
80
+
81
+	return tx.create(tableConfig, c)
82
+}
83
+
84
+// UpdateConfig updates an existing config in the store.
85
+// Returns ErrNotExist if the config doesn't exist.
86
+func UpdateConfig(tx Tx, c *api.Config) error {
87
+	// Ensure the name is either not in use or already used by this same Config.
88
+	if existing := tx.lookup(tableConfig, indexName, strings.ToLower(c.Spec.Annotations.Name)); existing != nil {
89
+		if existing.GetID() != c.ID {
90
+			return ErrNameConflict
91
+		}
92
+	}
93
+
94
+	return tx.update(tableConfig, c)
95
+}
96
+
97
+// DeleteConfig removes a config from the store.
98
+// Returns ErrNotExist if the config doesn't exist.
99
+func DeleteConfig(tx Tx, id string) error {
100
+	return tx.delete(tableConfig, id)
101
+}
102
+
103
+// GetConfig looks up a config by ID.
104
+// Returns nil if the config doesn't exist.
105
+func GetConfig(tx ReadTx, id string) *api.Config {
106
+	c := tx.get(tableConfig, id)
107
+	if c == nil {
108
+		return nil
109
+	}
110
+	return c.(*api.Config)
111
+}
112
+
113
+// FindConfigs selects a set of configs and returns them.
114
+func FindConfigs(tx ReadTx, by By) ([]*api.Config, error) {
115
+	checkType := func(by By) error {
116
+		switch by.(type) {
117
+		case byName, byNamePrefix, byIDPrefix, byCustom, byCustomPrefix:
118
+			return nil
119
+		default:
120
+			return ErrInvalidFindBy
121
+		}
122
+	}
123
+
124
+	configList := []*api.Config{}
125
+	appendResult := func(o api.StoreObject) {
126
+		configList = append(configList, o.(*api.Config))
127
+	}
128
+
129
+	err := tx.find(tableConfig, by, checkType, appendResult)
130
+	return configList, err
131
+}
... ...
@@ -33,6 +33,7 @@ const (
33 33
 	indexMembership   = "membership"
34 34
 	indexNetwork      = "network"
35 35
 	indexSecret       = "secret"
36
+	indexConfig       = "config"
36 37
 	indexKind         = "kind"
37 38
 	indexCustom       = "custom"
38 39
 
... ...
@@ -696,6 +697,12 @@ func (tx readTx) findIterators(table string, by By, checkType func(By) error) ([
696 696
 			return nil, err
697 697
 		}
698 698
 		return []memdb.ResultIterator{it}, nil
699
+	case byReferencedConfigID:
700
+		it, err := tx.memDBTx.Get(table, indexConfig, string(v))
701
+		if err != nil {
702
+			return nil, err
703
+		}
704
+		return []memdb.ResultIterator{it}, nil
699 705
 	case byKind:
700 706
 		it, err := tx.memDBTx.Get(table, indexKind, string(v))
701 707
 		if err != nil {
... ...
@@ -40,6 +40,11 @@ func init() {
40 40
 					AllowMissing: true,
41 41
 					Indexer:      serviceIndexerBySecret{},
42 42
 				},
43
+				indexConfig: {
44
+					Name:         indexConfig,
45
+					AllowMissing: true,
46
+					Indexer:      serviceIndexerByConfig{},
47
+				},
43 48
 				indexCustom: {
44 49
 					Name:         indexCustom,
45 50
 					Indexer:      api.ServiceCustomIndexer{},
... ...
@@ -131,7 +136,7 @@ func GetService(tx ReadTx, id string) *api.Service {
131 131
 func FindServices(tx ReadTx, by By) ([]*api.Service, error) {
132 132
 	checkType := func(by By) error {
133 133
 		switch by.(type) {
134
-		case byName, byNamePrefix, byIDPrefix, byRuntime, byReferencedNetworkID, byReferencedSecretID, byCustom, byCustomPrefix:
134
+		case byName, byNamePrefix, byIDPrefix, byRuntime, byReferencedNetworkID, byReferencedSecretID, byReferencedConfigID, byCustom, byCustomPrefix:
135 135
 			return nil
136 136
 		default:
137 137
 			return ErrInvalidFindBy
... ...
@@ -214,3 +219,30 @@ func (si serviceIndexerBySecret) FromObject(obj interface{}) (bool, [][]byte, er
214 214
 
215 215
 	return len(secretIDs) != 0, secretIDs, nil
216 216
 }
217
+
218
+type serviceIndexerByConfig struct{}
219
+
220
+func (si serviceIndexerByConfig) FromArgs(args ...interface{}) ([]byte, error) {
221
+	return fromArgs(args...)
222
+}
223
+
224
+func (si serviceIndexerByConfig) FromObject(obj interface{}) (bool, [][]byte, error) {
225
+	s, ok := obj.(*api.Service)
226
+	if !ok {
227
+		panic("unexpected type passed to FromObject")
228
+	}
229
+
230
+	container := s.Spec.Task.GetContainer()
231
+	if container == nil {
232
+		return false, nil, nil
233
+	}
234
+
235
+	var configIDs [][]byte
236
+
237
+	for _, configRef := range container.Configs {
238
+		// Add the null character as a terminator
239
+		configIDs = append(configIDs, []byte(configRef.ConfigID+"\x00"))
240
+	}
241
+
242
+	return len(configIDs) != 0, configIDs, nil
243
+}
... ...
@@ -64,6 +64,11 @@ func init() {
64 64
 					AllowMissing: true,
65 65
 					Indexer:      taskIndexerBySecret{},
66 66
 				},
67
+				indexConfig: {
68
+					Name:         indexConfig,
69
+					AllowMissing: true,
70
+					Indexer:      taskIndexerByConfig{},
71
+				},
67 72
 				indexCustom: {
68 73
 					Name:         indexCustom,
69 74
 					Indexer:      api.TaskCustomIndexer{},
... ...
@@ -143,7 +148,7 @@ func GetTask(tx ReadTx, id string) *api.Task {
143 143
 func FindTasks(tx ReadTx, by By) ([]*api.Task, error) {
144 144
 	checkType := func(by By) error {
145 145
 		switch by.(type) {
146
-		case byName, byNamePrefix, byIDPrefix, byRuntime, byDesiredState, byTaskState, byNode, byService, bySlot, byReferencedNetworkID, byReferencedSecretID, byCustom, byCustomPrefix:
146
+		case byName, byNamePrefix, byIDPrefix, byRuntime, byDesiredState, byTaskState, byNode, byService, bySlot, byReferencedNetworkID, byReferencedSecretID, byReferencedConfigID, byCustom, byCustomPrefix:
147 147
 			return nil
148 148
 		default:
149 149
 			return ErrInvalidFindBy
... ...
@@ -295,6 +300,33 @@ func (ti taskIndexerBySecret) FromObject(obj interface{}) (bool, [][]byte, error
295 295
 	return len(secretIDs) != 0, secretIDs, nil
296 296
 }
297 297
 
298
+type taskIndexerByConfig struct{}
299
+
300
+func (ti taskIndexerByConfig) FromArgs(args ...interface{}) ([]byte, error) {
301
+	return fromArgs(args...)
302
+}
303
+
304
+func (ti taskIndexerByConfig) FromObject(obj interface{}) (bool, [][]byte, error) {
305
+	t, ok := obj.(*api.Task)
306
+	if !ok {
307
+		panic("unexpected type passed to FromObject")
308
+	}
309
+
310
+	container := t.Spec.GetContainer()
311
+	if container == nil {
312
+		return false, nil, nil
313
+	}
314
+
315
+	var configIDs [][]byte
316
+
317
+	for _, configRef := range container.Configs {
318
+		// Add the null character as a terminator
319
+		configIDs = append(configIDs, []byte(configRef.ConfigID+"\x00"))
320
+	}
321
+
322
+	return len(configIDs) != 0, configIDs, nil
323
+}
324
+
298 325
 type taskIndexerByTaskState struct{}
299 326
 
300 327
 func (ts taskIndexerByTaskState) FromArgs(args ...interface{}) ([]byte, error) {
... ...
@@ -1,6 +1,7 @@
1 1
 package node
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"crypto/tls"
5 6
 	"encoding/json"
6 7
 	"io/ioutil"
... ...
@@ -25,6 +26,7 @@ import (
25 25
 	"github.com/docker/swarmkit/manager"
26 26
 	"github.com/docker/swarmkit/manager/encryption"
27 27
 	"github.com/docker/swarmkit/remotes"
28
+	"github.com/docker/swarmkit/watch"
28 29
 	"github.com/docker/swarmkit/xnet"
29 30
 	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
30 31
 	"github.com/pkg/errors"
... ...
@@ -129,7 +131,7 @@ type Node struct {
129 129
 	err              error
130 130
 	agent            *agent.Agent
131 131
 	manager          *manager.Manager
132
-	notifyNodeChange chan *api.Node // used to send role updates from the dispatcher api on promotion/demotion
132
+	notifyNodeChange chan *agent.NodeChanges // used by the agent to relay node updates from the dispatcher Session stream to (*Node).run
133 133
 	unlockKey        []byte
134 134
 }
135 135
 
... ...
@@ -172,7 +174,7 @@ func New(c *Config) (*Node, error) {
172 172
 		stopped:          make(chan struct{}),
173 173
 		closed:           make(chan struct{}),
174 174
 		ready:            make(chan struct{}),
175
-		notifyNodeChange: make(chan *api.Node, 1),
175
+		notifyNodeChange: make(chan *agent.NodeChanges, 1),
176 176
 		unlockKey:        c.UnlockKey,
177 177
 	}
178 178
 
... ...
@@ -235,7 +237,8 @@ func (n *Node) run(ctx context.Context) (err error) {
235 235
 		}
236 236
 	}(ctx)
237 237
 
238
-	securityConfig, err := n.loadSecurityConfig(ctx)
238
+	paths := ca.NewConfigPaths(filepath.Join(n.config.StateDir, certDirectory))
239
+	securityConfig, err := n.loadSecurityConfig(ctx, paths)
239 240
 	if err != nil {
240 241
 		return err
241 242
 	}
... ...
@@ -274,24 +277,44 @@ func (n *Node) run(ctx context.Context) (err error) {
274 274
 			select {
275 275
 			case <-agentDone:
276 276
 				return
277
-			case node := <-n.notifyNodeChange:
278
-				// If the server is sending us a ForceRenewal State, renew
279
-				if node.Certificate.Status.State == api.IssuanceStateRotate {
280
-					renewCert()
281
-					continue
282
-				}
277
+			case nodeChanges := <-n.notifyNodeChange:
283 278
 				n.Lock()
284
-				// If we got a role change, renew
285
-				role := ca.WorkerRole
286
-				if node.Role == api.NodeRoleManager {
287
-					role = ca.ManagerRole
279
+				currentRole := n.role
280
+				n.Unlock()
281
+
282
+				if nodeChanges.Node != nil {
283
+					role := ca.WorkerRole
284
+					if nodeChanges.Node.Role == api.NodeRoleManager {
285
+						role = ca.ManagerRole
286
+					}
287
+
288
+					// If the server is sending us a ForceRenewal State, or if the new node role doesn't match our current role, renew
289
+					if currentRole != role || nodeChanges.Node.Certificate.Status.State == api.IssuanceStateRotate {
290
+						renewCert()
291
+					}
288 292
 				}
289
-				if n.role == role {
290
-					n.Unlock()
291
-					continue
293
+
294
+				if nodeChanges.RootCert != nil {
295
+					// We only want to update the root CA if this is a worker node.  Manager nodes directly watch the raft
296
+					// store and update the root CA, with the necessary signer, from the raft store (since the managers
297
+					// need the CA key as well to potentially issue new TLS certificates).
298
+					if currentRole == ca.ManagerRole || bytes.Equal(nodeChanges.RootCert, securityConfig.RootCA().Certs) {
299
+						continue
300
+					}
301
+					newRootCA, err := ca.NewRootCA(nodeChanges.RootCert, nil, nil, ca.DefaultNodeCertExpiration, nil)
302
+					if err != nil {
303
+						log.G(ctx).WithError(err).Error("invalid new root certificate from the dispatcher")
304
+						continue
305
+					}
306
+					if err := ca.SaveRootCA(newRootCA, paths.RootCA); err != nil {
307
+						log.G(ctx).WithError(err).Error("could not save new root certificate from the dispatcher")
308
+						continue
309
+					}
310
+					if err := securityConfig.UpdateRootCA(&newRootCA, newRootCA.Pool); err != nil {
311
+						log.G(ctx).WithError(err).Error("could not use new root CA from dispatcher")
312
+						continue
313
+					}
292 314
 				}
293
-				n.Unlock()
294
-				renewCert()
295 315
 			}
296 316
 		}
297 317
 	}()
... ...
@@ -322,12 +345,12 @@ func (n *Node) run(ctx context.Context) (err error) {
322 322
 	var managerErr error
323 323
 	var agentErr error
324 324
 	go func() {
325
-		managerErr = n.superviseManager(ctx, securityConfig, managerReady, forceCertRenewal) // store err and loop
325
+		managerErr = n.superviseManager(ctx, securityConfig, paths.RootCA, managerReady, forceCertRenewal) // store err and loop
326 326
 		wg.Done()
327 327
 		cancel()
328 328
 	}()
329 329
 	go func() {
330
-		agentErr = n.runAgent(ctx, db, securityConfig.ClientTLSCreds, agentReady)
330
+		agentErr = n.runAgent(ctx, db, securityConfig, agentReady)
331 331
 		wg.Done()
332 332
 		cancel()
333 333
 		close(agentDone)
... ...
@@ -401,7 +424,7 @@ func (n *Node) Err(ctx context.Context) error {
401 401
 	}
402 402
 }
403 403
 
404
-func (n *Node) runAgent(ctx context.Context, db *bolt.DB, creds credentials.TransportCredentials, ready chan<- struct{}) error {
404
+func (n *Node) runAgent(ctx context.Context, db *bolt.DB, securityConfig *ca.SecurityConfig, ready chan<- struct{}) error {
405 405
 	waitCtx, waitCancel := context.WithCancel(ctx)
406 406
 	remotesCh := n.remotes.WaitSelect(ctx)
407 407
 	controlCh := n.ListenControlSocket(waitCtx)
... ...
@@ -428,13 +451,28 @@ waitPeer:
428 428
 	default:
429 429
 	}
430 430
 
431
+	secChangeQueue := watch.NewQueue()
432
+	defer secChangeQueue.Close()
433
+	secChangesCh, secChangesCancel := secChangeQueue.Watch()
434
+	defer secChangesCancel()
435
+	securityConfig.SetWatch(secChangeQueue)
436
+
437
+	rootCA := securityConfig.RootCA()
438
+	issuer := securityConfig.IssuerInfo()
439
+
431 440
 	a, err := agent.New(&agent.Config{
432 441
 		Hostname:         n.config.Hostname,
433 442
 		ConnBroker:       n.connBroker,
434 443
 		Executor:         n.config.Executor,
435 444
 		DB:               db,
436 445
 		NotifyNodeChange: n.notifyNodeChange,
437
-		Credentials:      creds,
446
+		NotifyTLSChange:  secChangesCh,
447
+		Credentials:      securityConfig.ClientTLSCreds,
448
+		NodeTLSInfo: &api.NodeTLSInfo{
449
+			TrustRoot:           rootCA.Certs,
450
+			CertIssuerPublicKey: issuer.PublicKey,
451
+			CertIssuerSubject:   issuer.Subject,
452
+		},
438 453
 	})
439 454
 	if err != nil {
440 455
 		return err
... ...
@@ -565,8 +603,7 @@ func (n *Node) Remotes() []api.Peer {
565 565
 	return remotes
566 566
 }
567 567
 
568
-func (n *Node) loadSecurityConfig(ctx context.Context) (*ca.SecurityConfig, error) {
569
-	paths := ca.NewConfigPaths(filepath.Join(n.config.StateDir, certDirectory))
568
+func (n *Node) loadSecurityConfig(ctx context.Context, paths *ca.SecurityConfigPaths) (*ca.SecurityConfig, error) {
570 569
 	var securityConfig *ca.SecurityConfig
571 570
 
572 571
 	krw := ca.NewKeyReadWriter(paths.Node, n.unlockKey, &manager.RaftDEKData{})
... ...
@@ -717,7 +754,7 @@ func (n *Node) waitRole(ctx context.Context, role string) error {
717 717
 	return nil
718 718
 }
719 719
 
720
-func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, workerRole <-chan struct{}) (bool, error) {
720
+func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, rootPaths ca.CertPaths, ready chan struct{}, workerRole <-chan struct{}) (bool, error) {
721 721
 	var remoteAPI *manager.RemoteAddrs
722 722
 	if n.config.ListenRemoteAPI != "" {
723 723
 		remoteAPI = &manager.RemoteAddrs{
... ...
@@ -741,6 +778,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
741 741
 		UnlockKey:        n.unlockKey,
742 742
 		Availability:     n.config.Availability,
743 743
 		PluginGetter:     n.config.PluginGetter,
744
+		RootCAPaths:      rootPaths,
744 745
 	})
745 746
 	if err != nil {
746 747
 		return false, err
... ...
@@ -789,7 +827,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
789 789
 	return clearData, nil
790 790
 }
791 791
 
792
-func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, forceCertRenewal chan struct{}) error {
792
+func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, rootPaths ca.CertPaths, ready chan struct{}, forceCertRenewal chan struct{}) error {
793 793
 	for {
794 794
 		if err := n.waitRole(ctx, ca.ManagerRole); err != nil {
795 795
 			return err
... ...
@@ -803,7 +841,7 @@ func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.Security
803 803
 			}
804 804
 		}()
805 805
 
806
-		wasRemoved, err := n.runManager(ctx, securityConfig, ready, workerRole)
806
+		wasRemoved, err := n.runManager(ctx, securityConfig, rootPaths, ready, workerRole)
807 807
 		if err != nil {
808 808
 			waitRoleCancel()
809 809
 			return errors.Wrap(err, "manager stopped")