Merge pull request #32392 from aluzzardi/revendor-swarmkit

[master] Re-vendor docker/swarmkit to d2e48a332063ccd4ea26b6262ee717de997de560
This commit is contained in:
Akihiro Suda 2017-04-06 13:18:17 +09:00 committed by GitHub
commit 2aed764baf
45 changed files with 8456 additions and 1823 deletions

View file

@ -97,7 +97,7 @@ func secretReferencesToGRPC(sr []*types.SecretReference) []*swarmapi.SecretRefer
}
if s.File != nil {
ref.Target = &swarmapi.SecretReference_File{
File: &swarmapi.SecretReference_FileTarget{
File: &swarmapi.FileTarget{
Name: s.File.Name,
UID: s.File.UID,
GID: s.File.GID,

View file

@ -105,7 +105,7 @@ github.com/docker/containerd 9048e5e50717ea4497b757314bad98ea3763c145
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
# cluster
github.com/docker/swarmkit b74ec2b81bb1d4a998f461bb2dc59b9408b7790f
github.com/docker/swarmkit d2e48a332063ccd4ea26b6262ee717de997de560
github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
github.com/gogo/protobuf 8d70fb3182befc465c4a1eac8ad4d38ff49778e2
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a

View file

@ -1,6 +1,7 @@
package agent
import (
"bytes"
"fmt"
"math/rand"
"reflect"
@ -44,6 +45,8 @@ type Agent struct {
stopOnce sync.Once // only allow stop to be called once
closed chan struct{} // only closed in run
err error // read only after closed is closed
nodeUpdatePeriod time.Duration
}
// New returns a new agent, ready for task dispatch.
@ -53,14 +56,15 @@ func New(config *Config) (*Agent, error) {
}
a := &Agent{
config: config,
sessionq: make(chan sessionOperation),
started: make(chan struct{}),
leaving: make(chan struct{}),
left: make(chan struct{}),
stopped: make(chan struct{}),
closed: make(chan struct{}),
ready: make(chan struct{}),
config: config,
sessionq: make(chan sessionOperation),
started: make(chan struct{}),
leaving: make(chan struct{}),
left: make(chan struct{}),
stopped: make(chan struct{}),
closed: make(chan struct{}),
ready: make(chan struct{}),
nodeUpdatePeriod: nodeUpdatePeriod,
}
a.worker = newWorker(config.DB, config.Executor, a)
@ -182,13 +186,15 @@ func (a *Agent) run(ctx context.Context) {
log.G(ctx).Debug("(*Agent).run")
defer log.G(ctx).Debug("(*Agent).run exited")
nodeTLSInfo := a.config.NodeTLSInfo
// get the node description
nodeDescription, err := a.nodeDescriptionWithHostname(ctx)
nodeDescription, err := a.nodeDescriptionWithHostname(ctx, nodeTLSInfo)
if err != nil {
log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: node description unavailable")
}
// nodeUpdateTicker is used to periodically check for updates to node description
nodeUpdateTicker := time.NewTicker(nodeUpdatePeriod)
nodeUpdateTicker := time.NewTicker(a.nodeUpdatePeriod)
defer nodeUpdateTicker.Stop()
var (
@ -214,6 +220,35 @@ func (a *Agent) run(ctx context.Context) {
a.worker.Listen(ctx, reporter)
updateNode := func() {
// skip updating if the registration isn't finished
if registered != nil {
return
}
// get the current node description
newNodeDescription, err := a.nodeDescriptionWithHostname(ctx, nodeTLSInfo)
if err != nil {
log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: updated node description unavailable")
}
// if newNodeDescription is nil, it will cause a panic when
// trying to create a session. Typically this can happen
// if the engine goes down
if newNodeDescription == nil {
return
}
// if the node description has changed, update it to the new one
// and close the session. The old session will be stopped and a
// new one will be created with the updated description
if !reflect.DeepEqual(nodeDescription, newNodeDescription) {
nodeDescription = newNodeDescription
// close the session
log.G(ctx).Info("agent: found node update")
session.sendError(nil)
}
}
for {
select {
case operation := <-sessionq:
@ -237,7 +272,8 @@ func (a *Agent) run(ctx context.Context) {
switch msg.Type {
case api.AssignmentsMessage_COMPLETE:
// Need to assign secrets before tasks, because tasks might depend on new secrets
// Need to assign secrets and configs before tasks,
// because tasks might depend on new secrets or configs
if err := a.worker.Assign(ctx, msg.Changes); err != nil {
log.G(ctx).WithError(err).Error("failed to synchronize worker assignments")
}
@ -247,7 +283,7 @@ func (a *Agent) run(ctx context.Context) {
}
}
case msg := <-session.messages:
if err := a.handleSessionMessage(ctx, msg); err != nil {
if err := a.handleSessionMessage(ctx, msg, nodeTLSInfo); err != nil {
log.G(ctx).WithError(err).Error("session message handler failed")
}
case sub := <-session.subscriptions:
@ -305,33 +341,17 @@ func (a *Agent) run(ctx context.Context) {
}
session = newSession(ctx, a, delay, session.sessionID, nodeDescription)
registered = session.registered
case ev := <-a.config.NotifyTLSChange:
// the TLS info has changed, so force a check to see if we need to restart the session
if tlsInfo, ok := ev.(*api.NodeTLSInfo); ok {
nodeTLSInfo = tlsInfo
updateNode()
nodeUpdateTicker.Stop()
nodeUpdateTicker = time.NewTicker(a.nodeUpdatePeriod)
}
case <-nodeUpdateTicker.C:
// skip this case if the registration isn't finished
if registered != nil {
continue
}
// get the current node description
newNodeDescription, err := a.nodeDescriptionWithHostname(ctx)
if err != nil {
log.G(ctx).WithError(err).WithField("agent", a.config.Executor).Error("agent: updated node description unavailable")
}
// if newNodeDescription is nil, it will cause a panic when
// trying to create a session. Typically this can happen
// if the engine goes down
if newNodeDescription == nil {
continue
}
// if the node description has changed, update it to the new one
// and close the session. The old session will be stopped and a
// new one will be created with the updated description
if !reflect.DeepEqual(nodeDescription, newNodeDescription) {
nodeDescription = newNodeDescription
// close the session
log.G(ctx).Info("agent: found node update")
session.sendError(nil)
}
// periodically check to see whether the node information has changed, and if so, restart the session
updateNode()
case <-a.stopped:
// TODO(stevvooe): Wait on shutdown and cleanup. May need to pump
// this loop a few times.
@ -347,7 +367,7 @@ func (a *Agent) run(ctx context.Context) {
}
}
func (a *Agent) handleSessionMessage(ctx context.Context, message *api.SessionMessage) error {
func (a *Agent) handleSessionMessage(ctx context.Context, message *api.SessionMessage, nti *api.NodeTLSInfo) error {
seen := map[api.Peer]struct{}{}
for _, manager := range message.Managers {
if manager.Peer.Addr == "" {
@ -358,16 +378,26 @@ func (a *Agent) handleSessionMessage(ctx context.Context, message *api.SessionMe
seen[*manager.Peer] = struct{}{}
}
if message.Node != nil {
if a.node == nil || !nodesEqual(a.node, message.Node) {
if a.config.NotifyNodeChange != nil {
a.config.NotifyNodeChange <- message.Node.Copy()
}
a.node = message.Node.Copy()
if err := a.config.Executor.Configure(ctx, a.node); err != nil {
log.G(ctx).WithError(err).Error("node configure failed")
}
var changes *NodeChanges
if message.Node != nil && (a.node == nil || !nodesEqual(a.node, message.Node)) {
if a.config.NotifyNodeChange != nil {
changes = &NodeChanges{Node: message.Node.Copy()}
}
a.node = message.Node.Copy()
if err := a.config.Executor.Configure(ctx, a.node); err != nil {
log.G(ctx).WithError(err).Error("node configure failed")
}
}
if len(message.RootCA) > 0 && !bytes.Equal(message.RootCA, nti.TrustRoot) {
if changes == nil {
changes = &NodeChanges{RootCert: message.RootCA}
} else {
changes.RootCert = message.RootCA
}
}
if changes != nil {
a.config.NotifyNodeChange <- changes
}
// prune managers not in list.
@ -517,12 +547,15 @@ func (a *Agent) Publisher(ctx context.Context, subscriptionID string) (exec.LogP
}
// nodeDescriptionWithHostname retrieves node description, and overrides hostname if available
func (a *Agent) nodeDescriptionWithHostname(ctx context.Context) (*api.NodeDescription, error) {
func (a *Agent) nodeDescriptionWithHostname(ctx context.Context, tlsInfo *api.NodeTLSInfo) (*api.NodeDescription, error) {
desc, err := a.config.Executor.Describe(ctx)
// Override hostname
if a.config.Hostname != "" && desc != nil {
desc.Hostname = a.config.Hostname
// Override hostname and TLS info
if desc != nil {
if a.config.Hostname != "" && desc != nil {
desc.Hostname = a.config.Hostname
}
desc.TLSInfo = tlsInfo
}
return desc, err
}

View file

@ -2,6 +2,7 @@ package agent
import (
"github.com/boltdb/bolt"
"github.com/docker/go-events"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/connectionbroker"
@ -9,6 +10,13 @@ import (
"google.golang.org/grpc/credentials"
)
// NodeChanges encapsulates changes that should be made to the node as per session messages
// from the dispatcher
type NodeChanges struct {
Node *api.Node
RootCert []byte
}
// Config provides values for an Agent.
type Config struct {
// Hostname the name of host for agent instance.
@ -25,10 +33,16 @@ type Config struct {
DB *bolt.DB
// NotifyNodeChange channel receives new node changes from session messages.
NotifyNodeChange chan<- *api.Node
NotifyNodeChange chan<- *NodeChanges
// NotifyTLSChange channel sends new TLS information changes, which can cause a session to restart
NotifyTLSChange <-chan events.Event
// Credentials is credentials for grpc connection to manager.
Credentials credentials.TransportCredentials
// NodeTLSInfo contains the starting node TLS info to bootstrap into the agent
NodeTLSInfo *api.NodeTLSInfo
}
func (c *Config) validate() error {
@ -44,5 +58,9 @@ func (c *Config) validate() error {
return errors.New("agent: database required")
}
if c.NodeTLSInfo == nil {
return errors.New("agent: Node TLS info is required")
}
return nil
}

View file

@ -0,0 +1,87 @@
package configs
import (
"sync"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/api"
)
// configs is a map that keeps all the currently available configs to the agent
// mapped by config ID.
type configs struct {
mu sync.RWMutex
m map[string]*api.Config
}
// NewManager returns a place to store configs.
func NewManager() exec.ConfigsManager {
return &configs{
m: make(map[string]*api.Config),
}
}
// Get returns a config by ID. If the config doesn't exist, returns nil.
func (r *configs) Get(configID string) *api.Config {
r.mu.RLock()
defer r.mu.RUnlock()
if r, ok := r.m[configID]; ok {
return r
}
return nil
}
// Add adds one or more configs to the config map.
func (r *configs) Add(configs ...api.Config) {
r.mu.Lock()
defer r.mu.Unlock()
for _, config := range configs {
r.m[config.ID] = config.Copy()
}
}
// Remove removes one or more configs by ID from the config map. Succeeds
// whether or not the given IDs are in the map.
func (r *configs) Remove(configs []string) {
r.mu.Lock()
defer r.mu.Unlock()
for _, config := range configs {
delete(r.m, config)
}
}
// Reset removes all the configs.
func (r *configs) Reset() {
r.mu.Lock()
defer r.mu.Unlock()
r.m = make(map[string]*api.Config)
}
// taskRestrictedConfigsProvider restricts the ids to the task.
type taskRestrictedConfigsProvider struct {
configs exec.ConfigGetter
configIDs map[string]struct{} // allow list of config ids
}
func (sp *taskRestrictedConfigsProvider) Get(configID string) *api.Config {
if _, ok := sp.configIDs[configID]; !ok {
return nil
}
return sp.configs.Get(configID)
}
// Restrict provides a getter that only allows access to the configs
// referenced by the task.
func Restrict(configs exec.ConfigGetter, t *api.Task) exec.ConfigGetter {
cids := map[string]struct{}{}
container := t.Spec.GetContainer()
if container != nil {
for _, configRef := range container.Configs {
cids[configRef.ConfigID] = struct{}{}
}
}
return &taskRestrictedConfigsProvider{configs: configs, configIDs: cids}
}

52
vendor/github.com/docker/swarmkit/agent/dependency.go generated vendored Normal file
View file

@ -0,0 +1,52 @@
package agent
import (
"github.com/docker/swarmkit/agent/configs"
"github.com/docker/swarmkit/agent/exec"
"github.com/docker/swarmkit/agent/secrets"
"github.com/docker/swarmkit/api"
)
type dependencyManager struct {
secrets exec.SecretsManager
configs exec.ConfigsManager
}
// NewDependencyManager creates a dependency manager object that wraps
// objects which provide access to various dependency types.
func NewDependencyManager() exec.DependencyManager {
return &dependencyManager{
secrets: secrets.NewManager(),
configs: configs.NewManager(),
}
}
func (d *dependencyManager) Secrets() exec.SecretsManager {
return d.secrets
}
func (d *dependencyManager) Configs() exec.ConfigsManager {
return d.configs
}
type dependencyGetter struct {
secrets exec.SecretGetter
configs exec.ConfigGetter
}
func (d *dependencyGetter) Secrets() exec.SecretGetter {
return d.secrets
}
func (d *dependencyGetter) Configs() exec.ConfigGetter {
return d.configs
}
// Restrict provides getters that only allows access to the dependencies
// referenced by the task.
func Restrict(dependencies exec.DependencyManager, t *api.Task) exec.DependencyGetter {
return &dependencyGetter{
secrets: secrets.Restrict(dependencies.Secrets(), t),
configs: configs.Restrict(dependencies.Configs(), t),
}
}

View file

@ -28,6 +28,26 @@ type SecretsProvider interface {
Secrets() SecretsManager
}
// ConfigsProvider is implemented by objects that can store configs,
// typically an executor.
type ConfigsProvider interface {
Configs() ConfigsManager
}
// DependencyManager is a meta-object that can keep track of typed objects
// such as secrets and configs.
type DependencyManager interface {
SecretsProvider
ConfigsProvider
}
// DependencyGetter is a meta-object that can provide access to typed objects
// such as secrets and configs.
type DependencyGetter interface {
Secrets() SecretGetter
Configs() ConfigGetter
}
// SecretGetter contains secret data necessary for the Controller.
type SecretGetter interface {
// Get returns the the secret with a specific secret ID, if available.
@ -43,3 +63,19 @@ type SecretsManager interface {
Remove(secrets []string) // remove the secrets by ID
Reset() // remove all secrets
}
// ConfigGetter contains config data necessary for the Controller.
type ConfigGetter interface {
// Get returns the the config with a specific config ID, if available.
// When the config is not available, the return will be nil.
Get(configID string) *api.Config
}
// ConfigsManager is the interface for config storage and updates.
type ConfigsManager interface {
ConfigGetter
Add(configs ...api.Config) // add one or more configs
Remove(configs []string) // remove the configs by ID
Reset() // remove all configs
}

View file

@ -23,12 +23,13 @@ type Worker interface {
// It is not safe to call any worker function after that.
Close()
// Assign assigns a complete set of tasks and secrets to a worker. Any task or secrets not included in
// this set will be removed.
// Assign assigns a complete set of tasks and configs/secrets to a
// worker. Any items not included in this set will be removed.
Assign(ctx context.Context, assignments []*api.AssignmentChange) error
// Updates updates an incremental set of tasks or secrets of the worker. Any task/secret not included
// either in added or removed will remain untouched.
// Updates updates an incremental set of tasks or configs/secrets of
// the worker. Any items not included either in added or removed will
// remain untouched.
Update(ctx context.Context, assignments []*api.AssignmentChange) error
// Listen to updates about tasks controlled by the worker. When first
@ -119,11 +120,11 @@ func (w *worker) Close() {
w.taskevents.Close()
}
// Assign assigns a full set of tasks and secrets to the worker.
// Assign assigns a full set of tasks, configs, and secrets to the worker.
// Any tasks not previously known will be started. Any tasks that are in the task set
// and already running will be updated, if possible. Any tasks currently running on
// the worker outside the task set will be terminated.
// Any secrets not in the set of assignments will be removed.
// Anything not in the set of assignments will be removed.
func (w *worker) Assign(ctx context.Context, assignments []*api.AssignmentChange) error {
w.mu.Lock()
defer w.mu.Unlock()
@ -136,20 +137,28 @@ func (w *worker) Assign(ctx context.Context, assignments []*api.AssignmentChange
"len(assignments)": len(assignments),
}).Debug("(*worker).Assign")
// Need to update secrets before tasks, because tasks might depend on new secrets
// Need to update dependencies before tasks
err := reconcileSecrets(ctx, w, assignments, true)
if err != nil {
return err
}
err = reconcileConfigs(ctx, w, assignments, true)
if err != nil {
return err
}
return reconcileTaskState(ctx, w, assignments, true)
}
// Update updates the set of tasks and secret for the worker.
// Update updates the set of tasks, configs, and secrets for the worker.
// Tasks in the added set will be added to the worker, and tasks in the removed set
// will be removed from the worker
// Secrets in the added set will be added to the worker, and secrets in the removed set
// will be removed from the worker.
// Configs in the added set will be added to the worker, and configs in the removed set
// will be removed from the worker.
func (w *worker) Update(ctx context.Context, assignments []*api.AssignmentChange) error {
w.mu.Lock()
defer w.mu.Unlock()
@ -167,6 +176,11 @@ func (w *worker) Update(ctx context.Context, assignments []*api.AssignmentChange
return err
}
err = reconcileConfigs(ctx, w, assignments, false)
if err != nil {
return err
}
return reconcileTaskState(ctx, w, assignments, false)
}
@ -318,7 +332,7 @@ func reconcileSecrets(ctx context.Context, w *worker, assignments []*api.Assignm
}
}
provider, ok := w.executor.(exec.SecretsProvider)
secretsProvider, ok := w.executor.(exec.SecretsProvider)
if !ok {
if len(updatedSecrets) != 0 || len(removedSecrets) != 0 {
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
return nil
}
secrets := provider.Secrets()
secrets := secretsProvider.Secrets()
log.G(ctx).WithFields(logrus.Fields{
"len(updatedSecrets)": len(updatedSecrets),
@ -344,6 +358,49 @@ func reconcileSecrets(ctx context.Context, w *worker, assignments []*api.Assignm
return nil
}
func reconcileConfigs(ctx context.Context, w *worker, assignments []*api.AssignmentChange, fullSnapshot bool) error {
var (
updatedConfigs []api.Config
removedConfigs []string
)
for _, a := range assignments {
if r := a.Assignment.GetConfig(); r != nil {
switch a.Action {
case api.AssignmentChange_AssignmentActionUpdate:
updatedConfigs = append(updatedConfigs, *r)
case api.AssignmentChange_AssignmentActionRemove:
removedConfigs = append(removedConfigs, r.ID)
}
}
}
configsProvider, ok := w.executor.(exec.ConfigsProvider)
if !ok {
if len(updatedConfigs) != 0 || len(removedConfigs) != 0 {
log.G(ctx).Warn("configs update ignored; executor does not support configs")
}
return nil
}
configs := configsProvider.Configs()
log.G(ctx).WithFields(logrus.Fields{
"len(updatedConfigs)": len(updatedConfigs),
"len(removedConfigs)": len(removedConfigs),
}).Debug("(*worker).reconcileConfigs")
// If this was a complete set of configs, we're going to clear the configs map and add all of them
if fullSnapshot {
configs.Reset()
} else {
configs.Remove(removedConfigs)
}
configs.Add(updatedConfigs...)
return nil
}
func (w *worker) Listen(ctx context.Context, reporter StatusReporter) {
w.mu.Lock()
defer w.mu.Unlock()

File diff suppressed because it is too large Load diff

View file

@ -92,7 +92,7 @@ service Control {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
};
// ListSecrets returns a `ListSecretResponse` with a list all non-internal `Secret`s being
// ListSecrets returns a `ListSecretResponse` with a list of all non-internal `Secret`s being
// managed, or all secrets matching any name in `ListSecretsRequest.Names`, any
// name prefix in `ListSecretsRequest.NamePrefixes`, any id in
// `ListSecretsRequest.SecretIDs`, or any id prefix in `ListSecretsRequest.IDPrefixes`.
@ -116,6 +116,51 @@ service Control {
rpc RemoveSecret(RemoveSecretRequest) returns (RemoveSecretResponse) {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
}
// --- config APIs ---
// GetConfig returns a `GetConfigResponse` with a `Config` with the same
// id as `GetConfigRequest.ConfigID`
// - Returns `NotFound` if the Config with the given id is not found.
// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
// - Returns an error if getting fails.
rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
}
// UpdateConfig returns a `UpdateConfigResponse` with a `Config` with the same
// id as `GetConfigRequest.ConfigID`
// - Returns `NotFound` if the Config with the given id is not found.
// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
// - Returns an error if updating fails.
rpc UpdateConfig(UpdateConfigRequest) returns (UpdateConfigResponse) {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
};
// ListConfigs returns a `ListConfigResponse` with a list of `Config`s being
// managed, or all configs matching any name in `ListConfigsRequest.Names`, any
// name prefix in `ListConfigsRequest.NamePrefixes`, any id in
// `ListConfigsRequest.ConfigIDs`, or any id prefix in `ListConfigsRequest.IDPrefixes`.
// - Returns an error if listing fails.
rpc ListConfigs(ListConfigsRequest) returns (ListConfigsResponse) {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
}
// CreateConfig creates and return a `CreateConfigResponse` with a `Config` based
// on the provided `CreateConfigRequest.ConfigSpec`.
// - Returns `InvalidArgument` if the `CreateConfigRequest.ConfigSpec` is malformed,
// or if the config data is too long or contains invalid characters.
// - Returns an error if the creation fails.
rpc CreateConfig(CreateConfigRequest) returns (CreateConfigResponse) {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
}
// RemoveConfig removes the config referenced by `RemoveConfigRequest.ID`.
// - Returns `InvalidArgument` if `RemoveConfigRequest.ID` is empty.
// - Returns `NotFound` if the a config named `RemoveConfigRequest.ID` is not found.
// - Returns an error if the deletion fails.
rpc RemoveConfig(RemoveConfigRequest) returns (RemoveConfigResponse) {
option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
}
}
message GetNodeRequest {
@ -396,7 +441,6 @@ message UpdateSecretResponse {
Secret secret = 1;
}
// ListSecretRequest is the request to list all non-internal secrets in the secret store,
// or all secrets filtered by (name or name prefix or id prefix) and labels.
message ListSecretsRequest {
@ -424,7 +468,7 @@ message CreateSecretRequest {
SecretSpec spec = 1;
}
// CreateSecretResponse contains the newly created `Secret`` corresponding to the
// CreateSecretResponse contains the newly created `Secret` corresponding to the
// name in `CreateSecretRequest`. The `Secret.Spec.Data` field should be nil instead
// of actually containing the secret bytes.
message CreateSecretResponse {
@ -440,3 +484,71 @@ message RemoveSecretRequest {
// RemoveSecretResponse is an empty object indicating the successful removal of
// a secret.
message RemoveSecretResponse {}
// GetConfigRequest is the request to get a `Config` object given a config id.
message GetConfigRequest {
string config_id = 1;
}
// GetConfigResponse contains the Config corresponding to the id in
// `GetConfigRequest`.
message GetConfigResponse {
Config config = 1;
}
message UpdateConfigRequest {
// ConfigID is the config ID to update.
string config_id = 1;
// ConfigVersion is the version of the config being updated.
Version config_version = 2;
// Spec is the new spec to apply to the Config
// Only some fields are allowed to be updated.
ConfigSpec spec = 3;
}
message UpdateConfigResponse {
Config config = 1;
}
// ListConfigRequest is the request to list all configs in the config store,
// or all configs filtered by (name or name prefix or id prefix) and labels.
message ListConfigsRequest {
message Filters {
repeated string names = 1;
repeated string id_prefixes = 2;
map<string, string> labels = 3;
repeated string name_prefixes = 4;
}
Filters filters = 1;
}
// ListConfigResponse contains a list of all the configs that match the name or
// name prefix filters provided in `ListConfigRequest`.
message ListConfigsResponse {
repeated Config configs = 1;
}
// CreateConfigRequest specifies a new config (it will not update an existing
// config) to create.
message CreateConfigRequest {
ConfigSpec spec = 1;
}
// CreateConfigResponse contains the newly created `Config` corresponding to the
// name in `CreateConfigRequest`.
message CreateConfigResponse {
Config config = 1;
}
// RemoveConfigRequest contains the ID of the config that should be removed. This
// removes all versions of the config.
message RemoveConfigRequest {
string config_id = 1;
}
// RemoveConfigResponse is an empty object indicating the successful removal of
// a config.
message RemoveConfigResponse {}

View file

@ -21,7 +21,8 @@ var Service = api.ServiceSpec{
},
Resources: &api.ResourceRequirements{},
Restart: &api.RestartPolicy{
Delay: gogotypes.DurationProto(5 * time.Second),
Condition: api.RestartOnAny,
Delay: gogotypes.DurationProto(5 * time.Second),
},
Placement: &api.Placement{},
},
@ -31,6 +32,12 @@ var Service = api.ServiceSpec{
Parallelism: 1,
Order: api.UpdateConfig_STOP_FIRST,
},
Rollback: &api.UpdateConfig{
FailureAction: api.UpdateConfig_PAUSE,
Monitor: gogotypes.DurationProto(5 * time.Second),
Parallelism: 1,
Order: api.UpdateConfig_STOP_FIRST,
},
}
// InterpolateService returns a ServiceSpec based on the provided spec, which
@ -79,5 +86,14 @@ func InterpolateService(origSpec *api.ServiceSpec) *api.ServiceSpec {
}
}
if spec.Rollback == nil {
spec.Rollback = Service.Rollback.Copy()
} else {
if spec.Rollback.Monitor == nil {
spec.Rollback.Monitor = &gogotypes.Duration{}
deepcopy.Copy(spec.Rollback.Monitor, Service.Rollback.Monitor)
}
}
return spec
}

View file

@ -154,6 +154,8 @@ type SessionMessage struct {
// Symmetric encryption key distributed by the lead manager. Used by agents
// for securing network bootstrapping and communication.
NetworkBootstrapKeys []*EncryptionKey `protobuf:"bytes,4,rep,name=network_bootstrap_keys,json=networkBootstrapKeys" json:"network_bootstrap_keys,omitempty"`
// Which root certificates to trust
RootCA []byte `protobuf:"bytes,5,opt,name=RootCA,proto3" json:"RootCA,omitempty"`
}
func (m *SessionMessage) Reset() { *m = SessionMessage{} }
@ -244,6 +246,7 @@ type Assignment struct {
// Types that are valid to be assigned to Item:
// *Assignment_Task
// *Assignment_Secret
// *Assignment_Config
Item isAssignment_Item `protobuf_oneof:"item"`
}
@ -263,9 +266,13 @@ type Assignment_Task struct {
type Assignment_Secret struct {
Secret *Secret `protobuf:"bytes,2,opt,name=secret,oneof"`
}
type Assignment_Config struct {
Config *Config `protobuf:"bytes,3,opt,name=config,oneof"`
}
func (*Assignment_Task) isAssignment_Item() {}
func (*Assignment_Secret) isAssignment_Item() {}
func (*Assignment_Config) isAssignment_Item() {}
func (m *Assignment) GetItem() isAssignment_Item {
if m != nil {
@ -288,11 +295,19 @@ func (m *Assignment) GetSecret() *Secret {
return nil
}
func (m *Assignment) GetConfig() *Config {
if x, ok := m.GetItem().(*Assignment_Config); ok {
return x.Config
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
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{}) {
return _Assignment_OneofMarshaler, _Assignment_OneofUnmarshaler, _Assignment_OneofSizer, []interface{}{
(*Assignment_Task)(nil),
(*Assignment_Secret)(nil),
(*Assignment_Config)(nil),
}
}
@ -310,6 +325,11 @@ func _Assignment_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if err := b.EncodeMessage(x.Secret); err != nil {
return err
}
case *Assignment_Config:
_ = b.EncodeVarint(3<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Config); err != nil {
return err
}
case nil:
default:
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
err := b.DecodeMessage(msg)
m.Item = &Assignment_Secret{msg}
return true, err
case 3: // item.config
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Config)
err := b.DecodeMessage(msg)
m.Item = &Assignment_Config{msg}
return true, err
default:
return false, nil
}
@ -355,6 +383,11 @@ func _Assignment_OneofSizer(msg proto.Message) (n int) {
n += proto.SizeVarint(2<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *Assignment_Config:
s := proto.Size(x.Config)
n += proto.SizeVarint(3<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
@ -513,6 +546,10 @@ func (m *SessionMessage) CopyFrom(src interface{}) {
}
}
if o.RootCA != nil {
m.RootCA = make([]byte, len(o.RootCA))
copy(m.RootCA, o.RootCA)
}
}
func (m *HeartbeatRequest) Copy() *HeartbeatRequest {
@ -678,6 +715,12 @@ func (m *Assignment) CopyFrom(src interface{}) {
}
github_com_docker_swarmkit_api_deepcopy.Copy(v.Secret, o.GetSecret())
m.Item = &v
case *Assignment_Config:
v := Assignment_Config{
Config: &Config{},
}
github_com_docker_swarmkit_api_deepcopy.Copy(v.Config, o.GetConfig())
m.Item = &v
}
}
@ -1148,6 +1191,12 @@ func (m *SessionMessage) MarshalTo(dAtA []byte) (int, error) {
i += n
}
}
if len(m.RootCA) > 0 {
dAtA[i] = 0x2a
i++
i = encodeVarintDispatcher(dAtA, i, uint64(len(m.RootCA)))
i += copy(dAtA[i:], m.RootCA)
}
return i, nil
}
@ -1420,6 +1469,20 @@ func (m *Assignment_Secret) MarshalTo(dAtA []byte) (int, error) {
}
return i, nil
}
func (m *Assignment_Config) MarshalTo(dAtA []byte) (int, error) {
i := 0
if m.Config != nil {
dAtA[i] = 0x1a
i++
i = encodeVarintDispatcher(dAtA, i, uint64(m.Config.Size()))
n8, err := m.Config.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n8
}
return i, nil
}
func (m *AssignmentChange) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1439,11 +1502,11 @@ func (m *AssignmentChange) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintDispatcher(dAtA, i, uint64(m.Assignment.Size()))
n8, err := m.Assignment.MarshalTo(dAtA[i:])
n9, err := m.Assignment.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n8
i += n9
}
if m.Action != 0 {
dAtA[i] = 0x10
@ -1860,6 +1923,10 @@ func (m *SessionMessage) Size() (n int) {
n += 1 + l + sovDispatcher(uint64(l))
}
}
l = len(m.RootCA)
if l > 0 {
n += 1 + l + sovDispatcher(uint64(l))
}
return n
}
@ -1976,6 +2043,15 @@ func (m *Assignment_Secret) Size() (n int) {
}
return n
}
func (m *Assignment_Config) Size() (n int) {
var l int
_ = l
if m.Config != nil {
l = m.Config.Size()
n += 1 + l + sovDispatcher(uint64(l))
}
return n
}
func (m *AssignmentChange) Size() (n int) {
var l int
_ = l
@ -2045,6 +2121,7 @@ func (this *SessionMessage) String() string {
`Node:` + strings.Replace(fmt.Sprintf("%v", this.Node), "Node", "Node", 1) + `,`,
`Managers:` + strings.Replace(fmt.Sprintf("%v", this.Managers), "WeightedPeer", "WeightedPeer", 1) + `,`,
`NetworkBootstrapKeys:` + strings.Replace(fmt.Sprintf("%v", this.NetworkBootstrapKeys), "EncryptionKey", "EncryptionKey", 1) + `,`,
`RootCA:` + fmt.Sprintf("%v", this.RootCA) + `,`,
`}`,
}, "")
return s
@ -2160,6 +2237,16 @@ func (this *Assignment_Secret) String() string {
}, "")
return s
}
func (this *Assignment_Config) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Assignment_Config{`,
`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
`}`,
}, "")
return s
}
func (this *AssignmentChange) String() string {
if this == nil {
return "nil"
@ -2457,6 +2544,37 @@ func (m *SessionMessage) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RootCA", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDispatcher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthDispatcher
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RootCA = append(m.RootCA[:0], dAtA[iNdEx:postIndex]...)
if m.RootCA == nil {
m.RootCA = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipDispatcher(dAtA[iNdEx:])
@ -3241,6 +3359,38 @@ func (m *Assignment) Unmarshal(dAtA []byte) error {
}
m.Item = &Assignment_Secret{v}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDispatcher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthDispatcher
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &Config{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Item = &Assignment_Config{v}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipDispatcher(dAtA[iNdEx:])
@ -3630,65 +3780,67 @@ var (
func init() { proto.RegisterFile("dispatcher.proto", fileDescriptorDispatcher) }
var fileDescriptorDispatcher = []byte{
// 949 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xcd, 0x6e, 0xe3, 0x54,
0x14, 0x8e, 0xd3, 0xd4, 0x6d, 0x4f, 0xda, 0x12, 0x2e, 0xa3, 0xc1, 0x58, 0x9a, 0x34, 0xb8, 0x4c,
0x54, 0x69, 0x8a, 0x3b, 0x84, 0x9f, 0x0d, 0x55, 0xa1, 0x69, 0x22, 0x35, 0x9a, 0x49, 0xa7, 0xba,
0xcd, 0xcc, 0x2c, 0x23, 0x27, 0x3e, 0xb8, 0x26, 0x8d, 0xaf, 0xf1, 0xbd, 0x99, 0x21, 0x48, 0x48,
0x48, 0x30, 0x12, 0x62, 0x85, 0x58, 0x75, 0xc3, 0x2b, 0xf0, 0x1c, 0x15, 0x2b, 0x96, 0xac, 0x0a,
0x93, 0x07, 0xe0, 0x01, 0x58, 0x21, 0xdb, 0xd7, 0x49, 0xc8, 0x24, 0x9d, 0xb4, 0xab, 0xc4, 0xe7,
0x7c, 0xdf, 0x39, 0x9f, 0xbf, 0x7b, 0x7c, 0x2e, 0xe4, 0x6c, 0x97, 0xfb, 0x96, 0x68, 0x9f, 0x62,
0x60, 0xfa, 0x01, 0x13, 0x8c, 0x10, 0x9b, 0xb5, 0x3b, 0x18, 0x98, 0xfc, 0xb9, 0x15, 0x74, 0x3b,
0xae, 0x30, 0x9f, 0x7d, 0xa0, 0x67, 0x45, 0xdf, 0x47, 0x1e, 0x03, 0xf4, 0x35, 0xd6, 0xfa, 0x12,
0xdb, 0x22, 0x79, 0xbc, 0xe5, 0x30, 0x87, 0x45, 0x7f, 0x77, 0xc2, 0x7f, 0x32, 0xfa, 0x96, 0x7f,
0xd6, 0x73, 0x5c, 0x6f, 0x27, 0xfe, 0x91, 0xc1, 0xbc, 0xc3, 0x98, 0x73, 0x86, 0x3b, 0xd1, 0x53,
0xab, 0xf7, 0xc5, 0x8e, 0xdd, 0x0b, 0x2c, 0xe1, 0x32, 0x99, 0x37, 0x5e, 0x28, 0xb0, 0x7e, 0x82,
0x9c, 0xbb, 0xcc, 0xa3, 0xf8, 0x55, 0x0f, 0xb9, 0x20, 0x55, 0xc8, 0xda, 0xc8, 0xdb, 0x81, 0xeb,
0x87, 0x38, 0x4d, 0x29, 0x28, 0x5b, 0xd9, 0xd2, 0xa6, 0xf9, 0xaa, 0x46, 0xf3, 0x88, 0xd9, 0x58,
0x19, 0x41, 0xe9, 0x38, 0x8f, 0x6c, 0x03, 0xf0, 0xb8, 0x70, 0xd3, 0xb5, 0xb5, 0x74, 0x41, 0xd9,
0x5a, 0x29, 0xaf, 0x0d, 0x2e, 0x37, 0x56, 0x64, 0xbb, 0x5a, 0x85, 0xae, 0x48, 0x40, 0xcd, 0x36,
0xbe, 0x4f, 0x0f, 0x75, 0xd4, 0x91, 0x73, 0xcb, 0xc1, 0x89, 0x02, 0xca, 0xd5, 0x05, 0xc8, 0x36,
0x64, 0x3c, 0x66, 0x63, 0xd4, 0x28, 0x5b, 0xd2, 0x66, 0xc9, 0xa5, 0x11, 0x8a, 0xec, 0xc2, 0x72,
0xd7, 0xf2, 0x2c, 0x07, 0x03, 0xae, 0x2d, 0x14, 0x16, 0xb6, 0xb2, 0xa5, 0xc2, 0x34, 0xc6, 0x53,
0x74, 0x9d, 0x53, 0x81, 0xf6, 0x31, 0x62, 0x40, 0x87, 0x0c, 0xf2, 0x14, 0x6e, 0x7b, 0x28, 0x9e,
0xb3, 0xa0, 0xd3, 0x6c, 0x31, 0x26, 0xb8, 0x08, 0x2c, 0xbf, 0xd9, 0xc1, 0x3e, 0xd7, 0x32, 0x51,
0xad, 0x77, 0xa7, 0xd5, 0xaa, 0x7a, 0xed, 0xa0, 0x1f, 0x59, 0xf3, 0x00, 0xfb, 0xf4, 0x96, 0x2c,
0x50, 0x4e, 0xf8, 0x0f, 0xb0, 0xcf, 0x8d, 0xcf, 0x21, 0x77, 0x88, 0x56, 0x20, 0x5a, 0x68, 0x89,
0xe4, 0x38, 0xae, 0x65, 0x83, 0x71, 0x0c, 0x6f, 0x8e, 0x55, 0xe0, 0x3e, 0xf3, 0x38, 0x92, 0x4f,
0x41, 0xf5, 0x31, 0x70, 0x99, 0x2d, 0x0f, 0xf3, 0x1d, 0x33, 0x9e, 0x0a, 0x33, 0x99, 0x0a, 0xb3,
0x22, 0xa7, 0xa2, 0xbc, 0x7c, 0x71, 0xb9, 0x91, 0x3a, 0xff, 0x6b, 0x43, 0xa1, 0x92, 0x62, 0xfc,
0x9c, 0x86, 0xb7, 0x1f, 0xfb, 0xb6, 0x25, 0xb0, 0x61, 0xf1, 0xce, 0x89, 0xb0, 0x44, 0x8f, 0xdf,
0x48, 0x1b, 0x79, 0x02, 0x4b, 0xbd, 0xa8, 0x50, 0xe2, 0xf9, 0xee, 0x34, 0x9f, 0x66, 0xf4, 0x32,
0x47, 0x91, 0x18, 0x41, 0x93, 0x62, 0x3a, 0x83, 0xdc, 0x64, 0x92, 0x6c, 0xc2, 0x92, 0xb0, 0x78,
0x67, 0x24, 0x0b, 0x06, 0x97, 0x1b, 0x6a, 0x08, 0xab, 0x55, 0xa8, 0x1a, 0xa6, 0x6a, 0x36, 0xf9,
0x04, 0x54, 0x1e, 0x91, 0xe4, 0xd4, 0xe4, 0xa7, 0xe9, 0x19, 0x53, 0x22, 0xd1, 0x86, 0x0e, 0xda,
0xab, 0x2a, 0x63, 0xaf, 0x8d, 0x5d, 0x58, 0x0d, 0xa3, 0x37, 0xb3, 0xc8, 0xd8, 0x93, 0xec, 0xe4,
0x1b, 0x30, 0x61, 0x31, 0xd4, 0xca, 0x35, 0x25, 0x32, 0x4c, 0x9b, 0x25, 0x90, 0xc6, 0x30, 0xa3,
0x0c, 0x64, 0x9f, 0x73, 0xd7, 0xf1, 0xba, 0xe8, 0x89, 0x1b, 0x6a, 0xf8, 0x06, 0x60, 0x54, 0x83,
0x98, 0x90, 0x09, 0x4b, 0xcb, 0xc9, 0x99, 0x29, 0xe0, 0x30, 0x45, 0x23, 0x1c, 0xf9, 0x08, 0x54,
0x8e, 0xed, 0x00, 0x85, 0xf4, 0x54, 0x9f, 0xc6, 0x38, 0x89, 0x10, 0x87, 0x29, 0x2a, 0xb1, 0x65,
0x15, 0x32, 0xae, 0xc0, 0xae, 0xf1, 0x22, 0x0d, 0xb9, 0x51, 0xf3, 0x83, 0x53, 0xcb, 0x73, 0x90,
0xec, 0x01, 0x58, 0xc3, 0x98, 0x14, 0x32, 0xf5, 0xa8, 0x46, 0x4c, 0x3a, 0xc6, 0x20, 0x75, 0x50,
0xad, 0x76, 0xb4, 0xcb, 0x42, 0x49, 0xeb, 0xa5, 0x8f, 0xaf, 0xe6, 0xc6, 0x5d, 0xc7, 0x02, 0xfb,
0x11, 0x99, 0xca, 0x22, 0x46, 0x6b, 0x5c, 0x62, 0x9c, 0x23, 0x45, 0x50, 0x1f, 0x1f, 0x57, 0xf6,
0x1b, 0xd5, 0x5c, 0x4a, 0xd7, 0x7f, 0xfa, 0xb5, 0x70, 0x7b, 0x12, 0x21, 0xc7, 0xb2, 0x08, 0x2a,
0xad, 0xd6, 0x1f, 0x3d, 0xa9, 0xe6, 0x94, 0xe9, 0x38, 0x8a, 0x5d, 0xf6, 0x0c, 0x8d, 0x7f, 0x95,
0xff, 0x1d, 0x64, 0x32, 0x0e, 0x9f, 0x41, 0x26, 0xbc, 0x16, 0x22, 0x0f, 0xd6, 0x4b, 0xf7, 0xae,
0x7e, 0x8f, 0x84, 0x65, 0x36, 0xfa, 0x3e, 0xd2, 0x88, 0x48, 0xee, 0x00, 0x58, 0xbe, 0x7f, 0xe6,
0x22, 0x6f, 0x0a, 0x16, 0x2f, 0x65, 0xba, 0x22, 0x23, 0x0d, 0x16, 0xa6, 0x03, 0xe4, 0xbd, 0x33,
0xc1, 0x9b, 0xae, 0xa7, 0x2d, 0xc4, 0x69, 0x19, 0xa9, 0x79, 0x64, 0x0f, 0x96, 0xda, 0x91, 0x39,
0xc9, 0xa2, 0x7b, 0x6f, 0x1e, 0x27, 0x69, 0x42, 0x32, 0xee, 0x42, 0x26, 0xd4, 0x42, 0x56, 0x61,
0xf9, 0xe0, 0x51, 0xfd, 0xf8, 0x61, 0x35, 0xf4, 0x8b, 0xbc, 0x01, 0xd9, 0xda, 0xd1, 0x01, 0xad,
0xd6, 0xab, 0x47, 0x8d, 0xfd, 0x87, 0x39, 0xa5, 0x74, 0xbe, 0x08, 0x50, 0x19, 0xde, 0x91, 0xe4,
0x6b, 0x58, 0x92, 0x73, 0x4a, 0x8c, 0xe9, 0xc3, 0x34, 0x7e, 0x7d, 0xe9, 0x57, 0x61, 0xa4, 0x23,
0xc6, 0xe6, 0xef, 0xbf, 0xfd, 0x73, 0x9e, 0xbe, 0x03, 0xab, 0x11, 0xe6, 0xfd, 0x70, 0x11, 0x63,
0x00, 0x6b, 0xf1, 0x93, 0x5c, 0xf3, 0xf7, 0x15, 0xf2, 0x2d, 0xac, 0x0c, 0x97, 0x29, 0x99, 0xfa,
0xae, 0x93, 0xdb, 0x5a, 0xbf, 0xfb, 0x1a, 0x94, 0xdc, 0x12, 0xf3, 0x08, 0x20, 0xbf, 0x28, 0x90,
0x9b, 0xdc, 0x33, 0xe4, 0xde, 0x35, 0x76, 0xa6, 0xbe, 0x3d, 0x1f, 0xf8, 0x3a, 0xa2, 0x7a, 0xb0,
0x18, 0x6d, 0x28, 0x52, 0x98, 0xb5, 0x0a, 0x86, 0xdd, 0x67, 0x23, 0x92, 0x73, 0x28, 0xce, 0xd1,
0xf1, 0xc7, 0xb4, 0x72, 0x5f, 0x21, 0x3f, 0x28, 0x90, 0x1d, 0x1b, 0x6d, 0x52, 0x7c, 0xcd, 0xec,
0x27, 0x1a, 0x8a, 0xf3, 0x7d, 0x23, 0x73, 0x4e, 0x44, 0x59, 0xbb, 0x78, 0x99, 0x4f, 0xfd, 0xf9,
0x32, 0x9f, 0xfa, 0x6e, 0x90, 0x57, 0x2e, 0x06, 0x79, 0xe5, 0x8f, 0x41, 0x5e, 0xf9, 0x7b, 0x90,
0x57, 0x5a, 0x6a, 0x74, 0x97, 0x7e, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0xa6, 0xd5,
0x2c, 0xde, 0x09, 0x00, 0x00,
// 983 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xf7, 0x38, 0xce, 0x26, 0x7e, 0x4e, 0x82, 0x19, 0xaa, 0xb0, 0xac, 0x54, 0xc7, 0x6c, 0x68,
0x14, 0xa9, 0x61, 0x53, 0xcc, 0x9f, 0x0b, 0x51, 0x20, 0x8e, 0x2d, 0xc5, 0x6a, 0x93, 0x46, 0x13,
0xb7, 0x3d, 0x5a, 0x6b, 0xef, 0x74, 0xb3, 0x38, 0xde, 0x59, 0x76, 0xc6, 0x2d, 0x3e, 0x20, 0x71,
0xa0, 0x12, 0xe2, 0x84, 0x38, 0x45, 0x42, 0x7c, 0x05, 0xc4, 0xc7, 0x88, 0x38, 0x71, 0xe4, 0x14,
0xa8, 0x3f, 0x00, 0x1f, 0x80, 0x13, 0xda, 0xd9, 0x59, 0xdb, 0x75, 0xed, 0xd4, 0xc9, 0xc9, 0x9e,
0x37, 0xbf, 0xdf, 0x9b, 0xdf, 0xbc, 0xf7, 0xdb, 0x37, 0x90, 0x77, 0x3c, 0x1e, 0xd8, 0xa2, 0x75,
0x4a, 0x43, 0x2b, 0x08, 0x99, 0x60, 0x18, 0x3b, 0xac, 0xd5, 0xa6, 0xa1, 0xc5, 0x9f, 0xdb, 0x61,
0xa7, 0xed, 0x09, 0xeb, 0xd9, 0x47, 0x46, 0x4e, 0xf4, 0x02, 0xca, 0x63, 0x80, 0xb1, 0xcc, 0x9a,
0x5f, 0xd1, 0x96, 0x48, 0x96, 0xb7, 0x5c, 0xe6, 0x32, 0xf9, 0x77, 0x3b, 0xfa, 0xa7, 0xa2, 0xef,
0x04, 0x67, 0x5d, 0xd7, 0xf3, 0xb7, 0xe3, 0x1f, 0x15, 0x2c, 0xb8, 0x8c, 0xb9, 0x67, 0x74, 0x5b,
0xae, 0x9a, 0xdd, 0xa7, 0xdb, 0x4e, 0x37, 0xb4, 0x85, 0xc7, 0xd4, 0xbe, 0xf9, 0x02, 0xc1, 0xca,
0x09, 0xe5, 0xdc, 0x63, 0x3e, 0xa1, 0x5f, 0x77, 0x29, 0x17, 0xb8, 0x0a, 0x39, 0x87, 0xf2, 0x56,
0xe8, 0x05, 0x11, 0x4e, 0x47, 0x45, 0xb4, 0x99, 0x2b, 0xad, 0x5b, 0xaf, 0x6b, 0xb4, 0x8e, 0x98,
0x43, 0x2b, 0x43, 0x28, 0x19, 0xe5, 0xe1, 0x2d, 0x00, 0x1e, 0x27, 0x6e, 0x78, 0x8e, 0x9e, 0x2e,
0xa2, 0xcd, 0x6c, 0x79, 0xb9, 0x7f, 0xb9, 0x96, 0x55, 0xc7, 0xd5, 0x2a, 0x24, 0xab, 0x00, 0x35,
0xc7, 0xfc, 0x25, 0x3d, 0xd0, 0x71, 0x48, 0x39, 0xb7, 0x5d, 0x3a, 0x96, 0x00, 0x5d, 0x9d, 0x00,
0x6f, 0x41, 0xc6, 0x67, 0x0e, 0x95, 0x07, 0xe5, 0x4a, 0xfa, 0x34, 0xb9, 0x44, 0xa2, 0xf0, 0x0e,
0x2c, 0x76, 0x6c, 0xdf, 0x76, 0x69, 0xc8, 0xf5, 0xb9, 0xe2, 0xdc, 0x66, 0xae, 0x54, 0x9c, 0xc4,
0x78, 0x42, 0x3d, 0xf7, 0x54, 0x50, 0xe7, 0x98, 0xd2, 0x90, 0x0c, 0x18, 0xf8, 0x09, 0xac, 0xfa,
0x54, 0x3c, 0x67, 0x61, 0xbb, 0xd1, 0x64, 0x4c, 0x70, 0x11, 0xda, 0x41, 0xa3, 0x4d, 0x7b, 0x5c,
0xcf, 0xc8, 0x5c, 0xef, 0x4f, 0xca, 0x55, 0xf5, 0x5b, 0x61, 0x4f, 0x96, 0xe6, 0x3e, 0xed, 0x91,
0x5b, 0x2a, 0x41, 0x39, 0xe1, 0xdf, 0xa7, 0x3d, 0x8e, 0x57, 0x41, 0x23, 0x8c, 0x89, 0xfd, 0x3d,
0x7d, 0xbe, 0x88, 0x36, 0x97, 0x88, 0x5a, 0x99, 0x5f, 0x42, 0xfe, 0x80, 0xda, 0xa1, 0x68, 0x52,
0x5b, 0x24, 0x6d, 0xba, 0x56, 0x79, 0xcc, 0x63, 0x78, 0x7b, 0x24, 0x03, 0x0f, 0x98, 0xcf, 0x29,
0xfe, 0x1c, 0xb4, 0x80, 0x86, 0x1e, 0x73, 0x54, 0x93, 0xdf, 0xb3, 0x62, 0xb7, 0x58, 0x89, 0x5b,
0xac, 0x8a, 0x72, 0x4b, 0x79, 0xf1, 0xe2, 0x72, 0x2d, 0x75, 0xfe, 0xf7, 0x1a, 0x22, 0x8a, 0x62,
0xfe, 0x94, 0x86, 0x77, 0x1f, 0x05, 0x8e, 0x2d, 0x68, 0xdd, 0xe6, 0xed, 0x13, 0x61, 0x8b, 0x2e,
0xbf, 0x91, 0x36, 0xfc, 0x18, 0x16, 0xba, 0x32, 0x51, 0xd2, 0x8b, 0x9d, 0x49, 0xf5, 0x9b, 0x72,
0x96, 0x35, 0x8c, 0xc4, 0x08, 0x92, 0x24, 0x33, 0x18, 0xe4, 0xc7, 0x37, 0xf1, 0x3a, 0x2c, 0x08,
0x9b, 0xb7, 0x87, 0xb2, 0xa0, 0x7f, 0xb9, 0xa6, 0x45, 0xb0, 0x5a, 0x85, 0x68, 0xd1, 0x56, 0xcd,
0xc1, 0x9f, 0x81, 0xc6, 0x25, 0x49, 0xb9, 0xa9, 0x30, 0x49, 0xcf, 0x88, 0x12, 0x85, 0x36, 0x0d,
0xd0, 0x5f, 0x57, 0x19, 0xd7, 0xda, 0xdc, 0x81, 0xa5, 0x28, 0x7a, 0xb3, 0x12, 0x99, 0xbb, 0x8a,
0x9d, 0x7c, 0x1b, 0x16, 0xcc, 0x47, 0x5a, 0xb9, 0x8e, 0x64, 0xc1, 0xf4, 0x69, 0x02, 0x49, 0x0c,
0x33, 0xcb, 0x80, 0xf7, 0x38, 0xf7, 0x5c, 0xbf, 0x43, 0x7d, 0x71, 0x43, 0x0d, 0xbf, 0x23, 0x80,
0x61, 0x12, 0x6c, 0x41, 0x26, 0xca, 0xad, 0xac, 0x33, 0x55, 0xc1, 0x41, 0x8a, 0x48, 0x1c, 0xfe,
0x04, 0x34, 0x4e, 0x5b, 0x21, 0x15, 0xaa, 0xa8, 0xc6, 0x24, 0xc6, 0x89, 0x44, 0x1c, 0xa4, 0x88,
0xc2, 0x46, 0xac, 0x16, 0xf3, 0x9f, 0x7a, 0xae, 0x3e, 0x37, 0x9d, 0xb5, 0x2f, 0x11, 0x11, 0x2b,
0xc6, 0x96, 0x35, 0xc8, 0x78, 0x82, 0x76, 0xcc, 0x17, 0x69, 0xc8, 0x0f, 0x25, 0xef, 0x9f, 0xda,
0xbe, 0x4b, 0xf1, 0x2e, 0x80, 0x3d, 0x88, 0x29, 0xf9, 0x13, 0x3b, 0x3c, 0x64, 0x92, 0x11, 0x06,
0x3e, 0x04, 0xcd, 0x6e, 0xc9, 0xd1, 0x18, 0x5d, 0x64, 0xa5, 0xf4, 0xe9, 0xd5, 0xdc, 0xf8, 0xd4,
0x91, 0xc0, 0x9e, 0x24, 0x13, 0x95, 0xc4, 0x6c, 0x8e, 0x4a, 0x8c, 0xf7, 0xf0, 0x06, 0x68, 0x8f,
0x8e, 0x2b, 0x7b, 0xf5, 0x6a, 0x3e, 0x65, 0x18, 0x3f, 0xfe, 0x5a, 0x5c, 0x1d, 0x47, 0x28, 0x37,
0x6f, 0x80, 0x46, 0xaa, 0x87, 0x0f, 0x1f, 0x57, 0xf3, 0x68, 0x32, 0x8e, 0xd0, 0x0e, 0x7b, 0x46,
0xcd, 0xff, 0xd0, 0x2b, 0xfd, 0x4f, 0x5c, 0xf4, 0x05, 0x64, 0xa2, 0x57, 0x46, 0xd6, 0x60, 0xa5,
0x74, 0xf7, 0xea, 0x7b, 0x24, 0x2c, 0xab, 0xde, 0x0b, 0x28, 0x91, 0x44, 0x7c, 0x1b, 0xc0, 0x0e,
0x82, 0x33, 0x8f, 0xf2, 0x86, 0x60, 0xf1, 0x8c, 0x27, 0x59, 0x15, 0xa9, 0xb3, 0x68, 0x3b, 0xa4,
0xbc, 0x7b, 0x26, 0x78, 0xc3, 0xf3, 0x65, 0x03, 0xb3, 0x24, 0xab, 0x22, 0x35, 0x1f, 0xef, 0xc2,
0x42, 0x4b, 0x16, 0x27, 0x99, 0x9b, 0x1f, 0xcc, 0x52, 0x49, 0x92, 0x90, 0xcc, 0x3b, 0x90, 0x89,
0xb4, 0xe0, 0x25, 0x58, 0xdc, 0x7f, 0x78, 0x78, 0xfc, 0xa0, 0x1a, 0xd5, 0x0b, 0xbf, 0x05, 0xb9,
0xda, 0xd1, 0x3e, 0xa9, 0x1e, 0x56, 0x8f, 0xea, 0x7b, 0x0f, 0xf2, 0xa8, 0x74, 0x3e, 0x0f, 0x50,
0x19, 0x3c, 0xb9, 0xf8, 0x1b, 0x58, 0x50, 0xf6, 0xc6, 0xe6, 0x64, 0x0b, 0x8e, 0xbe, 0x86, 0xc6,
0x55, 0x18, 0x55, 0x11, 0x73, 0xfd, 0x8f, 0xdf, 0xfe, 0x3d, 0x4f, 0xdf, 0x86, 0x25, 0x89, 0xf9,
0x30, 0x9a, 0xeb, 0x34, 0x84, 0xe5, 0x78, 0xa5, 0x5e, 0x8d, 0x7b, 0x08, 0x7f, 0x0b, 0xd9, 0xc1,
0x0c, 0xc6, 0x13, 0xef, 0x3a, 0x3e, 0xe4, 0x8d, 0x3b, 0x6f, 0x40, 0xa9, 0xe1, 0x32, 0x8b, 0x00,
0xfc, 0x33, 0x82, 0xfc, 0xf8, 0x78, 0xc2, 0x77, 0xaf, 0x31, 0x6a, 0x8d, 0xad, 0xd9, 0xc0, 0xd7,
0x11, 0xd5, 0x85, 0x79, 0x39, 0xd8, 0x70, 0x71, 0xda, 0x00, 0x19, 0x9c, 0x3e, 0x1d, 0x91, 0xf4,
0x61, 0x63, 0x86, 0x13, 0x7f, 0x48, 0xa3, 0x7b, 0x08, 0x7f, 0x8f, 0x20, 0x37, 0x62, 0x6d, 0xbc,
0xf1, 0x06, 0xef, 0x27, 0x1a, 0x36, 0x66, 0xfb, 0x46, 0x66, 0x74, 0x44, 0x59, 0xbf, 0x78, 0x59,
0x48, 0xfd, 0xf5, 0xb2, 0x90, 0xfa, 0xae, 0x5f, 0x40, 0x17, 0xfd, 0x02, 0xfa, 0xb3, 0x5f, 0x40,
0xff, 0xf4, 0x0b, 0xa8, 0xa9, 0xc9, 0x27, 0xf8, 0xe3, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x6c,
0xba, 0x38, 0xbd, 0x2d, 0x0a, 0x00, 0x00,
}

View file

@ -126,6 +126,9 @@ message SessionMessage {
// Symmetric encryption key distributed by the lead manager. Used by agents
// for securing network bootstrapping and communication.
repeated EncryptionKey network_bootstrap_keys = 4;
// Which root certificates to trust
bytes RootCA = 5;
}
// HeartbeatRequest provides identifying properties for a single heartbeat.
@ -174,6 +177,7 @@ message Assignment {
oneof item {
Task task = 1;
Secret secret = 2;
Config config = 3;
}
}

View file

@ -269,9 +269,7 @@ func (*Cluster) ProtoMessage() {}
func (*Cluster) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{7} }
// Secret represents a secret that should be passed to a container or a node,
// and is immutable. It wraps the `spec` provided by the user with useful
// information that is generated from the secret data in the `spec`, such as
// the digest and size of the secret data.
// and is immutable.
type Secret struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Meta Meta `protobuf:"bytes,2,opt,name=meta" json:"meta"`
@ -286,6 +284,20 @@ func (m *Secret) Reset() { *m = Secret{} }
func (*Secret) ProtoMessage() {}
func (*Secret) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{8} }
// Config represents a set of configuration files that should be passed to a
// container.
type Config struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Meta Meta `protobuf:"bytes,2,opt,name=meta" json:"meta"`
// Spec contains the actual config data, as well as any context around the
// config data that the user provides.
Spec ConfigSpec `protobuf:"bytes,3,opt,name=spec" json:"spec"`
}
func (m *Config) Reset() { *m = Config{} }
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{9} }
// Resource is a top-level object with externally defined content and indexing.
// SwarmKit can serve as a store for these objects without understanding their
// meanings.
@ -304,7 +316,7 @@ type Resource struct {
func (m *Resource) Reset() { *m = Resource{} }
func (*Resource) ProtoMessage() {}
func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{9} }
func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{10} }
// Extension declares a type of "resource" object. This message provides some
// metadata about the objects.
@ -317,7 +329,7 @@ type Extension struct {
func (m *Extension) Reset() { *m = Extension{} }
func (*Extension) ProtoMessage() {}
func (*Extension) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{10} }
func (*Extension) Descriptor() ([]byte, []int) { return fileDescriptorObjects, []int{11} }
func init() {
proto.RegisterType((*Meta)(nil), "docker.swarmkit.v1.Meta")
@ -330,6 +342,7 @@ func init() {
proto.RegisterType((*Network)(nil), "docker.swarmkit.v1.Network")
proto.RegisterType((*Cluster)(nil), "docker.swarmkit.v1.Cluster")
proto.RegisterType((*Secret)(nil), "docker.swarmkit.v1.Secret")
proto.RegisterType((*Config)(nil), "docker.swarmkit.v1.Config")
proto.RegisterType((*Resource)(nil), "docker.swarmkit.v1.Resource")
proto.RegisterType((*Extension)(nil), "docker.swarmkit.v1.Extension")
}
@ -629,6 +642,23 @@ func (m *Secret) CopyFrom(src interface{}) {
github_com_docker_swarmkit_api_deepcopy.Copy(&m.Spec, &o.Spec)
}
func (m *Config) Copy() *Config {
if m == nil {
return nil
}
o := &Config{}
o.CopyFrom(m)
return o
}
func (m *Config) CopyFrom(src interface{}) {
o := src.(*Config)
*m = *o
github_com_docker_swarmkit_api_deepcopy.Copy(&m.Meta, &o.Meta)
github_com_docker_swarmkit_api_deepcopy.Copy(&m.Spec, &o.Spec)
}
func (m *Resource) Copy() *Resource {
if m == nil {
return nil
@ -1377,6 +1407,46 @@ func (m *Secret) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *Config) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Config) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.ID) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintObjects(dAtA, i, uint64(len(m.ID)))
i += copy(dAtA[i:], m.ID)
}
dAtA[i] = 0x12
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
n38, err := m.Meta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n38
dAtA[i] = 0x1a
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Spec.Size()))
n39, err := m.Spec.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n39
return i, nil
}
func (m *Resource) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1401,19 +1471,19 @@ func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
n38, err := m.Meta.MarshalTo(dAtA[i:])
n40, err := m.Meta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n38
i += n40
dAtA[i] = 0x1a
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
n39, err := m.Annotations.MarshalTo(dAtA[i:])
n41, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n39
i += n41
if len(m.Kind) > 0 {
dAtA[i] = 0x22
i++
@ -1424,11 +1494,11 @@ func (m *Resource) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Payload.Size()))
n40, err := m.Payload.MarshalTo(dAtA[i:])
n42, err := m.Payload.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n40
i += n42
}
return i, nil
}
@ -1457,19 +1527,19 @@ func (m *Extension) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Meta.Size()))
n41, err := m.Meta.MarshalTo(dAtA[i:])
n43, err := m.Meta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n41
i += n43
dAtA[i] = 0x1a
i++
i = encodeVarintObjects(dAtA, i, uint64(m.Annotations.Size()))
n42, err := m.Annotations.MarshalTo(dAtA[i:])
n44, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n42
i += n44
if len(m.Description) > 0 {
dAtA[i] = 0x22
i++
@ -1783,6 +1853,20 @@ func (m *Secret) Size() (n int) {
return n
}
func (m *Config) Size() (n int) {
var l int
_ = l
l = len(m.ID)
if l > 0 {
n += 1 + l + sovObjects(uint64(l))
}
l = m.Meta.Size()
n += 1 + l + sovObjects(uint64(l))
l = m.Spec.Size()
n += 1 + l + sovObjects(uint64(l))
return n
}
func (m *Resource) Size() (n int) {
var l int
_ = l
@ -3212,6 +3296,223 @@ func (indexer SecretCustomIndexer) FromObject(obj interface{}) (bool, [][]byte,
return customIndexer("", &m.Spec.Annotations)
}
type ConfigCheckFunc func(t1, t2 *Config) bool
type EventCreateConfig struct {
Config *Config
Checks []ConfigCheckFunc
}
func (e EventCreateConfig) Matches(apiEvent github_com_docker_go_events.Event) bool {
typedEvent, ok := apiEvent.(EventCreateConfig)
if !ok {
return false
}
for _, check := range e.Checks {
if !check(e.Config, typedEvent.Config) {
return false
}
}
return true
}
type EventUpdateConfig struct {
Config *Config
OldConfig *Config
Checks []ConfigCheckFunc
}
func (e EventUpdateConfig) Matches(apiEvent github_com_docker_go_events.Event) bool {
typedEvent, ok := apiEvent.(EventUpdateConfig)
if !ok {
return false
}
for _, check := range e.Checks {
if !check(e.Config, typedEvent.Config) {
return false
}
}
return true
}
type EventDeleteConfig struct {
Config *Config
Checks []ConfigCheckFunc
}
func (e EventDeleteConfig) Matches(apiEvent github_com_docker_go_events.Event) bool {
typedEvent, ok := apiEvent.(EventDeleteConfig)
if !ok {
return false
}
for _, check := range e.Checks {
if !check(e.Config, typedEvent.Config) {
return false
}
}
return true
}
func (m *Config) CopyStoreObject() StoreObject {
return m.Copy()
}
func (m *Config) GetMeta() Meta {
return m.Meta
}
func (m *Config) SetMeta(meta Meta) {
m.Meta = meta
}
func (m *Config) GetID() string {
return m.ID
}
func (m *Config) EventCreate() Event {
return EventCreateConfig{Config: m}
}
func (m *Config) EventUpdate(oldObject StoreObject) Event {
if oldObject != nil {
return EventUpdateConfig{Config: m, OldConfig: oldObject.(*Config)}
} else {
return EventUpdateConfig{Config: m}
}
}
func (m *Config) EventDelete() Event {
return EventDeleteConfig{Config: m}
}
func ConfigCheckID(v1, v2 *Config) bool {
return v1.ID == v2.ID
}
func ConfigCheckIDPrefix(v1, v2 *Config) bool {
return strings.HasPrefix(v2.ID, v1.ID)
}
func ConfigCheckName(v1, v2 *Config) bool {
return v1.Spec.Annotations.Name == v2.Spec.Annotations.Name
}
func ConfigCheckNamePrefix(v1, v2 *Config) bool {
return strings.HasPrefix(v2.Spec.Annotations.Name, v1.Spec.Annotations.Name)
}
func ConfigCheckCustom(v1, v2 *Config) bool {
return checkCustom(v1.Spec.Annotations, v2.Spec.Annotations)
}
func ConfigCheckCustomPrefix(v1, v2 *Config) bool {
return checkCustomPrefix(v1.Spec.Annotations, v2.Spec.Annotations)
}
func ConvertConfigWatch(action WatchActionKind, filters []*SelectBy) ([]Event, error) {
var (
m Config
checkFuncs []ConfigCheckFunc
)
for _, filter := range filters {
switch v := filter.By.(type) {
case *SelectBy_ID:
if m.ID != "" {
return nil, errConflictingFilters
}
m.ID = v.ID
checkFuncs = append(checkFuncs, ConfigCheckID)
case *SelectBy_IDPrefix:
if m.ID != "" {
return nil, errConflictingFilters
}
m.ID = v.IDPrefix
checkFuncs = append(checkFuncs, ConfigCheckIDPrefix)
case *SelectBy_Name:
if m.Spec.Annotations.Name != "" {
return nil, errConflictingFilters
}
m.Spec.Annotations.Name = v.Name
checkFuncs = append(checkFuncs, ConfigCheckName)
case *SelectBy_NamePrefix:
if m.Spec.Annotations.Name != "" {
return nil, errConflictingFilters
}
m.Spec.Annotations.Name = v.NamePrefix
checkFuncs = append(checkFuncs, ConfigCheckNamePrefix)
case *SelectBy_Custom:
if len(m.Spec.Annotations.Indices) != 0 {
return nil, errConflictingFilters
}
m.Spec.Annotations.Indices = []IndexEntry{{Key: v.Custom.Index, Val: v.Custom.Value}}
checkFuncs = append(checkFuncs, ConfigCheckCustom)
case *SelectBy_CustomPrefix:
if len(m.Spec.Annotations.Indices) != 0 {
return nil, errConflictingFilters
}
m.Spec.Annotations.Indices = []IndexEntry{{Key: v.CustomPrefix.Index, Val: v.CustomPrefix.Value}}
checkFuncs = append(checkFuncs, ConfigCheckCustomPrefix)
}
}
var events []Event
if (action & WatchActionKindCreate) != 0 {
events = append(events, EventCreateConfig{Config: &m, Checks: checkFuncs})
}
if (action & WatchActionKindUpdate) != 0 {
events = append(events, EventUpdateConfig{Config: &m, Checks: checkFuncs})
}
if (action & WatchActionKindRemove) != 0 {
events = append(events, EventDeleteConfig{Config: &m, Checks: checkFuncs})
}
if len(events) == 0 {
return nil, errUnrecognizedAction
}
return events, nil
}
type ConfigIndexerByID struct{}
func (indexer ConfigIndexerByID) FromArgs(args ...interface{}) ([]byte, error) {
return fromArgs(args...)
}
func (indexer ConfigIndexerByID) PrefixFromArgs(args ...interface{}) ([]byte, error) {
return prefixFromArgs(args...)
}
func (indexer ConfigIndexerByID) FromObject(obj interface{}) (bool, []byte, error) {
m := obj.(*Config)
return true, []byte(m.ID + "\x00"), nil
}
type ConfigIndexerByName struct{}
func (indexer ConfigIndexerByName) FromArgs(args ...interface{}) ([]byte, error) {
return fromArgs(args...)
}
func (indexer ConfigIndexerByName) PrefixFromArgs(args ...interface{}) ([]byte, error) {
return prefixFromArgs(args...)
}
func (indexer ConfigIndexerByName) FromObject(obj interface{}) (bool, []byte, error) {
m := obj.(*Config)
val := m.Spec.Annotations.Name
return true, []byte(strings.ToLower(val) + "\x00"), nil
}
type ConfigCustomIndexer struct{}
func (indexer ConfigCustomIndexer) FromArgs(args ...interface{}) ([]byte, error) {
return fromArgs(args...)
}
func (indexer ConfigCustomIndexer) PrefixFromArgs(args ...interface{}) ([]byte, error) {
return prefixFromArgs(args...)
}
func (indexer ConfigCustomIndexer) FromObject(obj interface{}) (bool, [][]byte, error) {
m := obj.(*Config)
return customIndexer("", &m.Spec.Annotations)
}
type ResourceCheckFunc func(t1, t2 *Resource) bool
type EventCreateResource struct {
@ -3708,6 +4009,15 @@ func NewStoreAction(c Event) (StoreAction, error) {
case EventDeleteSecret:
sa.Action = StoreActionKindRemove
sa.Target = &StoreAction_Secret{Secret: v.Secret}
case EventCreateConfig:
sa.Action = StoreActionKindCreate
sa.Target = &StoreAction_Config{Config: v.Config}
case EventUpdateConfig:
sa.Action = StoreActionKindUpdate
sa.Target = &StoreAction_Config{Config: v.Config}
case EventDeleteConfig:
sa.Action = StoreActionKindRemove
sa.Target = &StoreAction_Config{Config: v.Config}
case EventCreateResource:
sa.Action = StoreActionKindCreate
sa.Target = &StoreAction_Resource{Resource: v.Resource}
@ -3812,6 +4122,19 @@ func EventFromStoreAction(sa StoreAction, oldObject StoreObject) (Event, error)
case StoreActionKindRemove:
return EventDeleteSecret{Secret: v.Secret}, nil
}
case *StoreAction_Config:
switch sa.Action {
case StoreActionKindCreate:
return EventCreateConfig{Config: v.Config}, nil
case StoreActionKindUpdate:
if oldObject != nil {
return EventUpdateConfig{Config: v.Config, OldConfig: oldObject.(*Config)}, nil
} else {
return EventUpdateConfig{Config: v.Config}, nil
}
case StoreActionKindRemove:
return EventDeleteConfig{Config: v.Config}, nil
}
case *StoreAction_Resource:
switch sa.Action {
case StoreActionKindCreate:
@ -3904,6 +4227,16 @@ func WatchMessageEvent(c Event) *WatchMessage_Event {
}
case EventDeleteSecret:
return &WatchMessage_Event{Action: WatchActionKindRemove, Object: &Object{Object: &Object_Secret{Secret: v.Secret}}}
case EventCreateConfig:
return &WatchMessage_Event{Action: WatchActionKindCreate, Object: &Object{Object: &Object_Config{Config: v.Config}}}
case EventUpdateConfig:
if v.OldConfig != nil {
return &WatchMessage_Event{Action: WatchActionKindUpdate, Object: &Object{Object: &Object_Config{Config: v.Config}}, OldObject: &Object{Object: &Object_Config{Config: v.OldConfig}}}
} else {
return &WatchMessage_Event{Action: WatchActionKindUpdate, Object: &Object{Object: &Object_Config{Config: v.Config}}}
}
case EventDeleteConfig:
return &WatchMessage_Event{Action: WatchActionKindRemove, Object: &Object{Object: &Object_Config{Config: v.Config}}}
case EventCreateResource:
return &WatchMessage_Event{Action: WatchActionKindCreate, Object: &Object{Object: &Object_Resource{Resource: v.Resource}}}
case EventUpdateResource:
@ -3948,6 +4281,8 @@ func ConvertWatchArgs(entries []*WatchRequest_WatchEntry) ([]Event, error) {
newEvents, err = ConvertClusterWatch(entry.Action, entry.Filters)
case "secret":
newEvents, err = ConvertSecretWatch(entry.Action, entry.Filters)
case "config":
newEvents, err = ConvertConfigWatch(entry.Action, entry.Filters)
default:
newEvents, err = ConvertResourceWatch(entry.Action, entry.Filters, entry.Kind)
case "extension":
@ -4120,6 +4455,18 @@ func (this *Secret) String() string {
}, "")
return s
}
func (this *Config) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Config{`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`Meta:` + strings.Replace(strings.Replace(this.Meta.String(), "Meta", "Meta", 1), `&`, ``, 1) + `,`,
`Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ConfigSpec", "ConfigSpec", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func (this *Resource) String() string {
if this == nil {
return "nil"
@ -6506,6 +6853,145 @@ func (m *Secret) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *Config) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowObjects
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Config: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Config: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowObjects
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthObjects
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowObjects
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthObjects
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Meta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowObjects
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthObjects
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipObjects(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthObjects
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Resource) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -6983,92 +7469,93 @@ var (
func init() { proto.RegisterFile("objects.proto", fileDescriptorObjects) }
var fileDescriptorObjects = []byte{
// 1390 bytes of a gzipped FileDescriptorProto
// 1405 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x57, 0xc1, 0x6f, 0x1b, 0x45,
0x17, 0xef, 0xda, 0x1b, 0xdb, 0xfb, 0x9c, 0x58, 0xf9, 0xa6, 0xf9, 0xf2, 0x6d, 0xf3, 0xe5, 0xb3,
0xf3, 0xb9, 0x02, 0x55, 0xa8, 0x72, 0x4a, 0x29, 0x28, 0x0d, 0x14, 0x6a, 0x27, 0x16, 0xb5, 0x4a,
0x69, 0x34, 0x2d, 0x2d, 0x37, 0x33, 0xd9, 0x9d, 0xba, 0x8b, 0xd7, 0x3b, 0xab, 0x9d, 0xb1, 0x8b,
0x6f, 0x88, 0x63, 0xfe, 0x81, 0xdc, 0x38, 0x70, 0xe2, 0x0e, 0x17, 0x2e, 0x9c, 0x7b, 0xe4, 0x84,
0x38, 0x45, 0xd4, 0xff, 0x05, 0x12, 0x07, 0x34, 0xb3, 0xb3, 0xce, 0xa6, 0x5e, 0x27, 0x2d, 0xaa,
0x2a, 0x4e, 0x9e, 0xd9, 0xf9, 0xfd, 0xde, 0xbc, 0xf7, 0xe6, 0x37, 0x6f, 0x9e, 0x61, 0x89, 0xed,
0x7f, 0x49, 0x1d, 0xc1, 0x1b, 0x61, 0xc4, 0x04, 0x43, 0xc8, 0x65, 0x4e, 0x9f, 0x46, 0x0d, 0xfe,
0x84, 0x44, 0x83, 0xbe, 0x27, 0x1a, 0xa3, 0xb7, 0xd7, 0xca, 0x62, 0x1c, 0x52, 0x0d, 0x58, 0x2b,
0xf3, 0x90, 0x3a, 0xc9, 0xa4, 0xd6, 0x63, 0xac, 0xe7, 0xd3, 0x4d, 0x35, 0xdb, 0x1f, 0x3e, 0xda,
0x14, 0xde, 0x80, 0x72, 0x41, 0x06, 0xa1, 0x06, 0xac, 0xf4, 0x58, 0x8f, 0xa9, 0xe1, 0xa6, 0x1c,
0xe9, 0xaf, 0x17, 0x9e, 0xa7, 0x91, 0x60, 0xac, 0x97, 0xce, 0x87, 0xfe, 0xb0, 0xe7, 0x05, 0x9b,
0xf1, 0x4f, 0xfc, 0xb1, 0xfe, 0x93, 0x01, 0xe6, 0x1d, 0x2a, 0x08, 0x7a, 0x1f, 0x8a, 0x23, 0x1a,
0x71, 0x8f, 0x05, 0xb6, 0xb1, 0x61, 0x5c, 0x2a, 0x5f, 0xfd, 0x6f, 0x63, 0xd6, 0xdf, 0xc6, 0x83,
0x18, 0xd2, 0x32, 0x9f, 0x1e, 0xd5, 0xce, 0xe1, 0x84, 0x81, 0xae, 0x03, 0x38, 0x11, 0x25, 0x82,
0xba, 0x5d, 0x22, 0xec, 0x9c, 0xe2, 0xaf, 0x35, 0x62, 0x57, 0x1a, 0x89, 0x2b, 0x8d, 0xfb, 0x49,
0x04, 0xd8, 0xd2, 0xe8, 0xa6, 0x90, 0xd4, 0x61, 0xe8, 0x26, 0xd4, 0xfc, 0xd9, 0x54, 0x8d, 0x6e,
0x8a, 0xfa, 0x0f, 0x26, 0x98, 0x9f, 0x32, 0x97, 0xa2, 0x55, 0xc8, 0x79, 0xae, 0x72, 0xdb, 0x6a,
0x15, 0x26, 0x47, 0xb5, 0x5c, 0x67, 0x17, 0xe7, 0x3c, 0x17, 0x5d, 0x05, 0x73, 0x40, 0x05, 0xd1,
0x0e, 0xd9, 0x59, 0x01, 0xc9, 0xd8, 0x75, 0x34, 0x0a, 0x8b, 0xde, 0x03, 0x53, 0x1e, 0x83, 0xf6,
0x64, 0x3d, 0x8b, 0x23, 0xf7, 0xbc, 0x17, 0x52, 0x27, 0xe1, 0x49, 0x3c, 0x6a, 0x43, 0xd9, 0xa5,
0xdc, 0x89, 0xbc, 0x50, 0xc8, 0x1c, 0x9a, 0x8a, 0x7e, 0x71, 0x1e, 0x7d, 0xf7, 0x18, 0x8a, 0xd3,
0x3c, 0xf4, 0x01, 0x14, 0xb8, 0x20, 0x62, 0xc8, 0xed, 0x05, 0x65, 0xa1, 0x3a, 0xd7, 0x01, 0x85,
0xd2, 0x2e, 0x68, 0x0e, 0xba, 0x05, 0x95, 0x01, 0x09, 0x48, 0x8f, 0x46, 0x5d, 0x6d, 0xa5, 0xa0,
0xac, 0xfc, 0x3f, 0x33, 0xf4, 0x18, 0x19, 0x1b, 0xc2, 0x4b, 0x83, 0xf4, 0x14, 0xb5, 0x01, 0x88,
0x10, 0xc4, 0x79, 0x3c, 0xa0, 0x81, 0xb0, 0x8b, 0xca, 0xca, 0x1b, 0x99, 0xbe, 0x50, 0xf1, 0x84,
0x45, 0xfd, 0xe6, 0x14, 0x8c, 0x53, 0x44, 0xf4, 0x31, 0x94, 0x1d, 0x1a, 0x09, 0xef, 0x91, 0xe7,
0x10, 0x41, 0xed, 0x92, 0xb2, 0x53, 0xcb, 0xb2, 0xb3, 0x73, 0x0c, 0xd3, 0x41, 0xa5, 0x99, 0xe8,
0x0a, 0x98, 0x11, 0xf3, 0xa9, 0x6d, 0x6d, 0x18, 0x97, 0x2a, 0xf3, 0x8f, 0x05, 0x33, 0x9f, 0x62,
0x85, 0xdc, 0x5e, 0x3d, 0x38, 0xac, 0x23, 0x58, 0x2e, 0x19, 0xcb, 0x86, 0x92, 0x86, 0x71, 0xc5,
0xf8, 0xdc, 0xf8, 0xc2, 0xa8, 0xff, 0x99, 0x87, 0xe2, 0x3d, 0x1a, 0x8d, 0x3c, 0xe7, 0xd5, 0x0a,
0xe7, 0xfa, 0x09, 0xe1, 0x64, 0xc6, 0xa8, 0xb7, 0x9d, 0xd1, 0xce, 0x16, 0x94, 0x68, 0xe0, 0x86,
0xcc, 0x0b, 0x84, 0x16, 0x4e, 0x66, 0x80, 0x6d, 0x8d, 0xc1, 0x53, 0x34, 0x6a, 0xc3, 0x52, 0x7c,
0x1f, 0xba, 0x27, 0x54, 0xb3, 0x91, 0x45, 0xff, 0x4c, 0x01, 0xf5, 0x71, 0x2f, 0x0e, 0x53, 0x33,
0xb4, 0x0b, 0x4b, 0x61, 0x44, 0x47, 0x1e, 0x1b, 0xf2, 0xae, 0x0a, 0xa2, 0xf0, 0x42, 0x41, 0xe0,
0xc5, 0x84, 0x25, 0x67, 0xe8, 0x43, 0x58, 0x94, 0xe4, 0x6e, 0x52, 0x47, 0xe0, 0xcc, 0x3a, 0x82,
0x55, 0xc9, 0xd3, 0x13, 0x74, 0x17, 0xfe, 0x7d, 0xc2, 0x8b, 0xa9, 0xa1, 0xf2, 0xd9, 0x86, 0xce,
0xa7, 0x3d, 0xd1, 0x1f, 0xb7, 0xd1, 0xc1, 0x61, 0xbd, 0x02, 0x8b, 0x69, 0x09, 0xd4, 0xbf, 0xcd,
0x41, 0x29, 0x49, 0x24, 0xba, 0xa6, 0xcf, 0xcc, 0x98, 0x9f, 0xb5, 0x04, 0xab, 0xe2, 0x8d, 0x8f,
0xeb, 0x1a, 0x2c, 0x84, 0x2c, 0x12, 0xdc, 0xce, 0x6d, 0xe4, 0xe7, 0x5d, 0xd1, 0x3d, 0x16, 0x89,
0x1d, 0x16, 0x3c, 0xf2, 0x7a, 0x38, 0x06, 0xa3, 0x87, 0x50, 0x1e, 0x79, 0x91, 0x18, 0x12, 0xbf,
0xeb, 0x85, 0xdc, 0xce, 0x2b, 0xee, 0x9b, 0xa7, 0x6d, 0xd9, 0x78, 0x10, 0xe3, 0x3b, 0x7b, 0xad,
0xca, 0xe4, 0xa8, 0x06, 0xd3, 0x29, 0xc7, 0xa0, 0x4d, 0x75, 0x42, 0xbe, 0x76, 0x07, 0xac, 0xe9,
0x0a, 0xba, 0x0c, 0x10, 0xc4, 0x37, 0xb2, 0x3b, 0x55, 0xf6, 0xd2, 0xe4, 0xa8, 0x66, 0xe9, 0x7b,
0xda, 0xd9, 0xc5, 0x96, 0x06, 0x74, 0x5c, 0x84, 0xc0, 0x24, 0xae, 0x1b, 0x29, 0x9d, 0x5b, 0x58,
0x8d, 0xeb, 0xdf, 0x17, 0xc0, 0xbc, 0x4f, 0x78, 0xff, 0x75, 0x57, 0x55, 0xb9, 0xe7, 0xcc, 0xcd,
0xb8, 0x0c, 0xc0, 0x63, 0xbd, 0xc9, 0x70, 0xcc, 0xe3, 0x70, 0xb4, 0x0a, 0x65, 0x38, 0x1a, 0x10,
0x87, 0xc3, 0x7d, 0x26, 0xd4, 0x25, 0x30, 0xb1, 0x1a, 0xa3, 0x8b, 0x50, 0x0c, 0x98, 0xab, 0xe8,
0x05, 0x45, 0x87, 0xc9, 0x51, 0xad, 0x20, 0x6b, 0x45, 0x67, 0x17, 0x17, 0xe4, 0x52, 0xc7, 0x95,
0x65, 0x8a, 0x04, 0x01, 0x13, 0x44, 0xd6, 0x60, 0xae, 0xcb, 0x5d, 0xa6, 0xfa, 0x9b, 0xc7, 0xb0,
0xa4, 0x4c, 0xa5, 0x98, 0xe8, 0x01, 0x9c, 0x4f, 0xfc, 0x4d, 0x1b, 0x2c, 0xbd, 0x8c, 0x41, 0xa4,
0x2d, 0xa4, 0x56, 0x52, 0xcf, 0x82, 0x35, 0xff, 0x59, 0x50, 0x19, 0xcc, 0x7a, 0x16, 0x5a, 0xb0,
0xe4, 0x52, 0xee, 0x45, 0xd4, 0x55, 0x65, 0x82, 0xaa, 0x9b, 0x59, 0xb9, 0xfa, 0xbf, 0xd3, 0x8c,
0x50, 0xbc, 0xa8, 0x39, 0x6a, 0x86, 0x9a, 0x50, 0xd2, 0xba, 0xe1, 0x76, 0x59, 0x69, 0xf7, 0x05,
0x9f, 0x83, 0x29, 0xed, 0x44, 0x99, 0x5b, 0x7c, 0xa9, 0x32, 0x77, 0x1d, 0xc0, 0x67, 0xbd, 0xae,
0x1b, 0x79, 0x23, 0x1a, 0xd9, 0x4b, 0xba, 0x49, 0xc8, 0xe0, 0xee, 0x2a, 0x04, 0xb6, 0x7c, 0xd6,
0x8b, 0x87, 0x33, 0x45, 0xa9, 0xf2, 0x72, 0x45, 0x69, 0x7b, 0xed, 0xe0, 0xb0, 0xbe, 0x0a, 0x2b,
0xe9, 0x1a, 0xb2, 0x65, 0xdc, 0x34, 0x6e, 0x19, 0x7b, 0x46, 0xfd, 0x1b, 0x03, 0xfe, 0x35, 0x13,
0x30, 0x7a, 0x17, 0x8a, 0x3a, 0xe4, 0xd3, 0x3a, 0x29, 0xcd, 0xc3, 0x09, 0x16, 0xad, 0x83, 0x25,
0xef, 0x1f, 0xe5, 0x9c, 0xc6, 0x95, 0xc5, 0xc2, 0xc7, 0x1f, 0x90, 0x0d, 0x45, 0xe2, 0x7b, 0x44,
0xae, 0xe5, 0xd5, 0x5a, 0x32, 0xad, 0x7f, 0x97, 0x83, 0xa2, 0x36, 0xf6, 0xba, 0xdf, 0x33, 0xbd,
0xed, 0xcc, 0xad, 0xbd, 0x01, 0x8b, 0xf1, 0x51, 0x69, 0xb9, 0x99, 0x67, 0x1e, 0x58, 0x39, 0xc6,
0xc7, 0x52, 0xbb, 0x01, 0xa6, 0x17, 0x92, 0x81, 0x7e, 0xcb, 0x32, 0x77, 0xee, 0xec, 0x35, 0xef,
0xdc, 0x0d, 0xe3, 0x5b, 0x53, 0x9a, 0x1c, 0xd5, 0x4c, 0xf9, 0x01, 0x2b, 0x5a, 0x66, 0xd5, 0xff,
0x71, 0x01, 0x8a, 0x3b, 0xfe, 0x90, 0x0b, 0x1a, 0xbd, 0xee, 0x24, 0xe9, 0x6d, 0x67, 0x92, 0xb4,
0x03, 0xc5, 0x88, 0x31, 0xd1, 0x75, 0xc8, 0x69, 0xf9, 0xc1, 0x8c, 0x89, 0x9d, 0x66, 0xab, 0x22,
0x89, 0xb2, 0x70, 0xc5, 0x73, 0x5c, 0x90, 0xd4, 0x1d, 0x82, 0x1e, 0xc2, 0x6a, 0x52, 0xee, 0xf7,
0x19, 0x13, 0x5c, 0x44, 0x24, 0xec, 0xf6, 0xe9, 0x58, 0x36, 0x02, 0xf9, 0x79, 0x8d, 0x5f, 0x3b,
0x70, 0xa2, 0xb1, 0x4a, 0xde, 0x6d, 0x3a, 0xc6, 0x2b, 0xda, 0x40, 0x2b, 0xe1, 0xdf, 0xa6, 0x63,
0x8e, 0x3e, 0x82, 0x75, 0x3a, 0x85, 0x49, 0x8b, 0x5d, 0x9f, 0x0c, 0xe4, 0x43, 0xd6, 0x75, 0x7c,
0xe6, 0xf4, 0x55, 0x2d, 0x35, 0xf1, 0x05, 0x9a, 0x36, 0xf5, 0x49, 0x8c, 0xd8, 0x91, 0x00, 0xc4,
0xc1, 0xde, 0xf7, 0x89, 0xd3, 0xf7, 0x3d, 0x2e, 0x7b, 0xfb, 0x54, 0x2f, 0x27, 0xcb, 0xa1, 0xf4,
0x6d, 0xeb, 0x94, 0x6c, 0x35, 0x5a, 0xc7, 0xdc, 0x54, 0x67, 0xc8, 0xdb, 0x81, 0x88, 0xc6, 0xf8,
0x3f, 0xfb, 0xd9, 0xab, 0xa8, 0x05, 0xe5, 0x61, 0x20, 0xb7, 0x8f, 0x73, 0x60, 0xbd, 0x68, 0x0e,
0x20, 0x66, 0xc9, 0xc8, 0xd7, 0x46, 0xb0, 0x7e, 0xda, 0xe6, 0x68, 0x19, 0xf2, 0x7d, 0x3a, 0x8e,
0xf5, 0x83, 0xe5, 0x10, 0xdd, 0x84, 0x85, 0x11, 0xf1, 0x87, 0x54, 0x2b, 0xe7, 0xad, 0xac, 0xfd,
0xb2, 0x4d, 0xe2, 0x98, 0xb8, 0x9d, 0xdb, 0x32, 0x32, 0x65, 0xfb, 0xb3, 0x01, 0x85, 0x7b, 0xd4,
0x89, 0xa8, 0x78, 0xa5, 0xaa, 0xdd, 0x3a, 0xa1, 0xda, 0x6a, 0x76, 0x97, 0x27, 0x77, 0x9d, 0x11,
0xed, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0x52, 0x6d, 0x09, 0x4f, 0xe7, 0x99, 0x01,
0xfc, 0x61, 0x40, 0x09, 0x53, 0xce, 0x86, 0xd1, 0x2b, 0xee, 0xb6, 0x9f, 0x7b, 0xb1, 0xf3, 0x7f,
0xfb, 0xc5, 0x46, 0x60, 0xf6, 0xbd, 0x40, 0xf7, 0x16, 0x58, 0x8d, 0x51, 0x03, 0x8a, 0x21, 0x19,
0xfb, 0x8c, 0xb8, 0xba, 0x06, 0xad, 0xcc, 0xfc, 0x21, 0x6d, 0x06, 0x63, 0x9c, 0x80, 0xb6, 0x57,
0x0e, 0x0e, 0xeb, 0xcb, 0x50, 0x49, 0x47, 0xfe, 0xd8, 0xa8, 0xff, 0x6a, 0x80, 0xd5, 0xfe, 0x4a,
0xd0, 0x40, 0x35, 0xb7, 0xff, 0xc8, 0xe0, 0x37, 0x66, 0xff, 0xb4, 0x5a, 0x27, 0xfe, 0x8f, 0x66,
0x1d, 0x6a, 0xcb, 0x7e, 0xfa, 0xac, 0x7a, 0xee, 0xb7, 0x67, 0xd5, 0x73, 0x5f, 0x4f, 0xaa, 0xc6,
0xd3, 0x49, 0xd5, 0xf8, 0x65, 0x52, 0x35, 0x7e, 0x9f, 0x54, 0x8d, 0xfd, 0x82, 0xca, 0xcf, 0x3b,
0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x01, 0x4f, 0xd2, 0x2a, 0xfa, 0x10, 0x00, 0x00,
0x17, 0xef, 0xda, 0x1b, 0xdb, 0xfb, 0x9c, 0x58, 0xf9, 0xa6, 0xf9, 0xf2, 0x6d, 0xf3, 0x05, 0x3b,
0xb8, 0x02, 0x55, 0xa8, 0x72, 0x4a, 0x29, 0x28, 0x0d, 0x14, 0x6a, 0x27, 0x11, 0xb5, 0x4a, 0x69,
0x34, 0x2d, 0x2d, 0x37, 0x33, 0xd9, 0x9d, 0xba, 0x8b, 0xd7, 0x3b, 0xab, 0x9d, 0xb1, 0x8b, 0x6f,
0x88, 0x63, 0xfe, 0x81, 0xdc, 0x38, 0xf4, 0xc4, 0x1d, 0x2e, 0x5c, 0x38, 0xf7, 0xc8, 0x09, 0x71,
0x8a, 0xa8, 0xff, 0x0b, 0x24, 0x0e, 0x68, 0x66, 0x67, 0x9d, 0x4d, 0xbd, 0x4e, 0x5a, 0x54, 0x45,
0x9c, 0x3c, 0xb3, 0xf3, 0xfb, 0xbd, 0x79, 0xef, 0xcd, 0x6f, 0xde, 0x3c, 0xc3, 0x02, 0xdb, 0xfb,
0x9a, 0x3a, 0x82, 0x37, 0xc2, 0x88, 0x09, 0x86, 0x90, 0xcb, 0x9c, 0x1e, 0x8d, 0x1a, 0xfc, 0x09,
0x89, 0xfa, 0x3d, 0x4f, 0x34, 0x86, 0xef, 0xae, 0x94, 0xc5, 0x28, 0xa4, 0x1a, 0xb0, 0x52, 0xe6,
0x21, 0x75, 0x92, 0x49, 0xad, 0xcb, 0x58, 0xd7, 0xa7, 0xeb, 0x6a, 0xb6, 0x37, 0x78, 0xb4, 0x2e,
0xbc, 0x3e, 0xe5, 0x82, 0xf4, 0x43, 0x0d, 0x58, 0xea, 0xb2, 0x2e, 0x53, 0xc3, 0x75, 0x39, 0xd2,
0x5f, 0x2f, 0xbc, 0x48, 0x23, 0xc1, 0x48, 0x2f, 0x9d, 0x0f, 0xfd, 0x41, 0xd7, 0x0b, 0xd6, 0xe3,
0x9f, 0xf8, 0x63, 0xfd, 0x67, 0x03, 0xcc, 0x3b, 0x54, 0x10, 0xf4, 0x21, 0x14, 0x87, 0x34, 0xe2,
0x1e, 0x0b, 0x6c, 0x63, 0xcd, 0xb8, 0x54, 0xbe, 0xfa, 0xff, 0xc6, 0xb4, 0xbf, 0x8d, 0x07, 0x31,
0xa4, 0x65, 0x3e, 0x3b, 0xac, 0x9d, 0xc3, 0x09, 0x03, 0x5d, 0x07, 0x70, 0x22, 0x4a, 0x04, 0x75,
0x3b, 0x44, 0xd8, 0x39, 0xc5, 0x5f, 0x69, 0xc4, 0xae, 0x34, 0x12, 0x57, 0x1a, 0xf7, 0x93, 0x08,
0xb0, 0xa5, 0xd1, 0x4d, 0x21, 0xa9, 0x83, 0xd0, 0x4d, 0xa8, 0xf9, 0xd3, 0xa9, 0x1a, 0xdd, 0x14,
0xf5, 0x1f, 0x4d, 0x30, 0x3f, 0x67, 0x2e, 0x45, 0xcb, 0x90, 0xf3, 0x5c, 0xe5, 0xb6, 0xd5, 0x2a,
0x8c, 0x0f, 0x6b, 0xb9, 0xf6, 0x36, 0xce, 0x79, 0x2e, 0xba, 0x0a, 0x66, 0x9f, 0x0a, 0xa2, 0x1d,
0xb2, 0xb3, 0x02, 0x92, 0xb1, 0xeb, 0x68, 0x14, 0x16, 0x7d, 0x00, 0xa6, 0x3c, 0x06, 0xed, 0xc9,
0x6a, 0x16, 0x47, 0xee, 0x79, 0x2f, 0xa4, 0x4e, 0xc2, 0x93, 0x78, 0xb4, 0x03, 0x65, 0x97, 0x72,
0x27, 0xf2, 0x42, 0x21, 0x73, 0x68, 0x2a, 0xfa, 0xc5, 0x59, 0xf4, 0xed, 0x23, 0x28, 0x4e, 0xf3,
0xd0, 0x47, 0x50, 0xe0, 0x82, 0x88, 0x01, 0xb7, 0xe7, 0x94, 0x85, 0xea, 0x4c, 0x07, 0x14, 0x4a,
0xbb, 0xa0, 0x39, 0xe8, 0x16, 0x54, 0xfa, 0x24, 0x20, 0x5d, 0x1a, 0x75, 0xb4, 0x95, 0x82, 0xb2,
0xf2, 0x66, 0x66, 0xe8, 0x31, 0x32, 0x36, 0x84, 0x17, 0xfa, 0xe9, 0x29, 0xda, 0x01, 0x20, 0x42,
0x10, 0xe7, 0x71, 0x9f, 0x06, 0xc2, 0x2e, 0x2a, 0x2b, 0x6f, 0x65, 0xfa, 0x42, 0xc5, 0x13, 0x16,
0xf5, 0x9a, 0x13, 0x30, 0x4e, 0x11, 0xd1, 0xa7, 0x50, 0x76, 0x68, 0x24, 0xbc, 0x47, 0x9e, 0x43,
0x04, 0xb5, 0x4b, 0xca, 0x4e, 0x2d, 0xcb, 0xce, 0xd6, 0x11, 0x4c, 0x07, 0x95, 0x66, 0xa2, 0x2b,
0x60, 0x46, 0xcc, 0xa7, 0xb6, 0xb5, 0x66, 0x5c, 0xaa, 0xcc, 0x3e, 0x16, 0xcc, 0x7c, 0x8a, 0x15,
0x72, 0x73, 0x79, 0xff, 0xa0, 0x8e, 0x60, 0xb1, 0x64, 0x2c, 0x1a, 0x4a, 0x1a, 0xc6, 0x15, 0xe3,
0x4b, 0xe3, 0x2b, 0xa3, 0xfe, 0x57, 0x1e, 0x8a, 0xf7, 0x68, 0x34, 0xf4, 0x9c, 0xd7, 0x2b, 0x9c,
0xeb, 0xc7, 0x84, 0x93, 0x19, 0xa3, 0xde, 0x76, 0x4a, 0x3b, 0x1b, 0x50, 0xa2, 0x81, 0x1b, 0x32,
0x2f, 0x10, 0x5a, 0x38, 0x99, 0x01, 0xee, 0x68, 0x0c, 0x9e, 0xa0, 0xd1, 0x0e, 0x2c, 0xc4, 0xf7,
0xa1, 0x73, 0x4c, 0x35, 0x6b, 0x59, 0xf4, 0x2f, 0x14, 0x50, 0x1f, 0xf7, 0xfc, 0x20, 0x35, 0x43,
0xdb, 0xb0, 0x10, 0x46, 0x74, 0xe8, 0xb1, 0x01, 0xef, 0xa8, 0x20, 0x0a, 0x2f, 0x15, 0x04, 0x9e,
0x4f, 0x58, 0x72, 0x86, 0x3e, 0x86, 0x79, 0x49, 0xee, 0x24, 0x75, 0x04, 0x4e, 0xad, 0x23, 0x58,
0x95, 0x3c, 0x3d, 0x41, 0x77, 0xe1, 0xbf, 0xc7, 0xbc, 0x98, 0x18, 0x2a, 0x9f, 0x6e, 0xe8, 0x7c,
0xda, 0x13, 0xfd, 0x71, 0x13, 0xed, 0x1f, 0xd4, 0x2b, 0x30, 0x9f, 0x96, 0x40, 0xfd, 0xfb, 0x1c,
0x94, 0x92, 0x44, 0xa2, 0x6b, 0xfa, 0xcc, 0x8c, 0xd9, 0x59, 0x4b, 0xb0, 0x2a, 0xde, 0xf8, 0xb8,
0xae, 0xc1, 0x5c, 0xc8, 0x22, 0xc1, 0xed, 0xdc, 0x5a, 0x7e, 0xd6, 0x15, 0xdd, 0x65, 0x91, 0xd8,
0x62, 0xc1, 0x23, 0xaf, 0x8b, 0x63, 0x30, 0x7a, 0x08, 0xe5, 0xa1, 0x17, 0x89, 0x01, 0xf1, 0x3b,
0x5e, 0xc8, 0xed, 0xbc, 0xe2, 0xbe, 0x7d, 0xd2, 0x96, 0x8d, 0x07, 0x31, 0xbe, 0xbd, 0xdb, 0xaa,
0x8c, 0x0f, 0x6b, 0x30, 0x99, 0x72, 0x0c, 0xda, 0x54, 0x3b, 0xe4, 0x2b, 0x77, 0xc0, 0x9a, 0xac,
0xa0, 0xcb, 0x00, 0x41, 0x7c, 0x23, 0x3b, 0x13, 0x65, 0x2f, 0x8c, 0x0f, 0x6b, 0x96, 0xbe, 0xa7,
0xed, 0x6d, 0x6c, 0x69, 0x40, 0xdb, 0x45, 0x08, 0x4c, 0xe2, 0xba, 0x91, 0xd2, 0xb9, 0x85, 0xd5,
0xb8, 0xfe, 0x43, 0x01, 0xcc, 0xfb, 0x84, 0xf7, 0xce, 0xba, 0xaa, 0xca, 0x3d, 0xa7, 0x6e, 0xc6,
0x65, 0x00, 0x1e, 0xeb, 0x4d, 0x86, 0x63, 0x1e, 0x85, 0xa3, 0x55, 0x28, 0xc3, 0xd1, 0x80, 0x38,
0x1c, 0xee, 0x33, 0xa1, 0x2e, 0x81, 0x89, 0xd5, 0x18, 0x5d, 0x84, 0x62, 0xc0, 0x5c, 0x45, 0x2f,
0x28, 0x3a, 0x8c, 0x0f, 0x6b, 0x05, 0x59, 0x2b, 0xda, 0xdb, 0xb8, 0x20, 0x97, 0xda, 0xae, 0x2c,
0x53, 0x24, 0x08, 0x98, 0x20, 0xb2, 0x06, 0x73, 0x5d, 0xee, 0x32, 0xd5, 0xdf, 0x3c, 0x82, 0x25,
0x65, 0x2a, 0xc5, 0x44, 0x0f, 0xe0, 0x7c, 0xe2, 0x6f, 0xda, 0x60, 0xe9, 0x55, 0x0c, 0x22, 0x6d,
0x21, 0xb5, 0x92, 0x7a, 0x16, 0xac, 0xd9, 0xcf, 0x82, 0xca, 0x60, 0xd6, 0xb3, 0xd0, 0x82, 0x05,
0x97, 0x72, 0x2f, 0xa2, 0xae, 0x2a, 0x13, 0x54, 0xdd, 0xcc, 0xca, 0xd5, 0x37, 0x4e, 0x32, 0x42,
0xf1, 0xbc, 0xe6, 0xa8, 0x19, 0x6a, 0x42, 0x49, 0xeb, 0x86, 0xdb, 0x65, 0xa5, 0xdd, 0x97, 0x7c,
0x0e, 0x26, 0xb4, 0x63, 0x65, 0x6e, 0xfe, 0x95, 0xca, 0xdc, 0x75, 0x00, 0x9f, 0x75, 0x3b, 0x6e,
0xe4, 0x0d, 0x69, 0x64, 0x2f, 0xe8, 0x26, 0x21, 0x83, 0xbb, 0xad, 0x10, 0xd8, 0xf2, 0x59, 0x37,
0x1e, 0x4e, 0x15, 0xa5, 0xca, 0xab, 0x15, 0xa5, 0xcd, 0x95, 0xfd, 0x83, 0xfa, 0x32, 0x2c, 0xa5,
0x6b, 0xc8, 0x86, 0x71, 0xd3, 0xb8, 0x65, 0xec, 0x1a, 0xf5, 0xef, 0x0c, 0xf8, 0xcf, 0x54, 0xc0,
0xe8, 0x7d, 0x28, 0xea, 0x90, 0x4f, 0xea, 0xa4, 0x34, 0x0f, 0x27, 0x58, 0xb4, 0x0a, 0x96, 0xbc,
0x7f, 0x94, 0x73, 0x1a, 0x57, 0x16, 0x0b, 0x1f, 0x7d, 0x40, 0x36, 0x14, 0x89, 0xef, 0x11, 0xb9,
0x96, 0x57, 0x6b, 0xc9, 0xb4, 0xfe, 0x34, 0x07, 0x45, 0x6d, 0xec, 0xac, 0xdf, 0x33, 0xbd, 0xed,
0xd4, 0xad, 0xbd, 0x01, 0xf3, 0xf1, 0x51, 0x69, 0xb9, 0x99, 0xa7, 0x1e, 0x58, 0x39, 0xc6, 0xc7,
0x52, 0xbb, 0x01, 0xa6, 0x17, 0x92, 0xbe, 0x7e, 0xcb, 0x32, 0x77, 0x6e, 0xef, 0x36, 0xef, 0xdc,
0x0d, 0xe3, 0x5b, 0x53, 0x1a, 0x1f, 0xd6, 0x4c, 0xf9, 0x01, 0x2b, 0x5a, 0x66, 0xd5, 0xff, 0x69,
0x0e, 0x8a, 0x5b, 0xfe, 0x80, 0x0b, 0x1a, 0x9d, 0x75, 0x92, 0xf4, 0xb6, 0x53, 0x49, 0xda, 0x82,
0x62, 0xc4, 0x98, 0xe8, 0x38, 0xe4, 0xa4, 0xfc, 0x60, 0xc6, 0xc4, 0x56, 0xb3, 0x55, 0x91, 0x44,
0x59, 0xb8, 0xe2, 0x39, 0x2e, 0x48, 0xea, 0x16, 0x41, 0x0f, 0x61, 0x39, 0x29, 0xf7, 0x7b, 0x8c,
0x09, 0x2e, 0x22, 0x12, 0x76, 0x7a, 0x74, 0x24, 0x1b, 0x81, 0xfc, 0xac, 0xc6, 0x6f, 0x27, 0x70,
0xa2, 0x91, 0x4a, 0xde, 0x6d, 0x3a, 0xc2, 0x4b, 0xda, 0x40, 0x2b, 0xe1, 0xdf, 0xa6, 0x23, 0x8e,
0x3e, 0x81, 0x55, 0x3a, 0x81, 0x49, 0x8b, 0x1d, 0x9f, 0xf4, 0xe5, 0x43, 0xd6, 0x71, 0x7c, 0xe6,
0xf4, 0x54, 0x2d, 0x35, 0xf1, 0x05, 0x9a, 0x36, 0xf5, 0x59, 0x8c, 0xd8, 0x92, 0x00, 0xc4, 0xc1,
0xde, 0xf3, 0x89, 0xd3, 0xf3, 0x3d, 0x2e, 0x7b, 0xfb, 0x54, 0x2f, 0x27, 0xcb, 0xa1, 0xf4, 0x6d,
0xe3, 0x84, 0x6c, 0x35, 0x5a, 0x47, 0xdc, 0x54, 0x67, 0xc8, 0x77, 0x02, 0x11, 0x8d, 0xf0, 0xff,
0xf6, 0xb2, 0x57, 0x51, 0x0b, 0xca, 0x83, 0x40, 0x6e, 0x1f, 0xe7, 0xc0, 0x7a, 0xd9, 0x1c, 0x40,
0xcc, 0x92, 0x91, 0xaf, 0x0c, 0x61, 0xf5, 0xa4, 0xcd, 0xd1, 0x22, 0xe4, 0x7b, 0x74, 0x14, 0xeb,
0x07, 0xcb, 0x21, 0xba, 0x09, 0x73, 0x43, 0xe2, 0x0f, 0xa8, 0x56, 0xce, 0x3b, 0x59, 0xfb, 0x65,
0x9b, 0xc4, 0x31, 0x71, 0x33, 0xb7, 0x61, 0x64, 0xca, 0xf6, 0x17, 0x03, 0x0a, 0xf7, 0xa8, 0x13,
0x51, 0xf1, 0x5a, 0x55, 0xbb, 0x71, 0x4c, 0xb5, 0xd5, 0xec, 0x2e, 0x4f, 0xee, 0x3a, 0x25, 0xda,
0x15, 0x28, 0x79, 0x81, 0xa0, 0x51, 0x40, 0x7c, 0xa5, 0xda, 0x12, 0x9e, 0xcc, 0x33, 0x03, 0x78,
0x6a, 0x40, 0x21, 0x6e, 0x83, 0xce, 0x3a, 0x80, 0x78, 0xd7, 0x17, 0x03, 0xc8, 0x74, 0xf2, 0x4f,
0x03, 0x4a, 0x98, 0x72, 0x36, 0x88, 0x5e, 0xf3, 0x5f, 0x82, 0x17, 0xda, 0x8a, 0xfc, 0x3f, 0x6e,
0x2b, 0x10, 0x98, 0x3d, 0x2f, 0xd0, 0x0d, 0x10, 0x56, 0x63, 0xd4, 0x80, 0x62, 0x48, 0x46, 0x3e,
0x23, 0xae, 0x2e, 0x94, 0x4b, 0x53, 0xff, 0x9a, 0x9b, 0xc1, 0x08, 0x27, 0xa0, 0xcd, 0xa5, 0xfd,
0x83, 0xfa, 0x22, 0x54, 0xd2, 0x91, 0x3f, 0x36, 0xea, 0xbf, 0x19, 0x60, 0xed, 0x7c, 0x23, 0x68,
0xa0, 0x3a, 0xf0, 0x7f, 0x65, 0xf0, 0x6b, 0xd3, 0xff, 0xac, 0xad, 0x63, 0x7f, 0x9a, 0xb3, 0x0e,
0xb5, 0x65, 0x3f, 0x7b, 0x5e, 0x3d, 0xf7, 0xfb, 0xf3, 0xea, 0xb9, 0x6f, 0xc7, 0x55, 0xe3, 0xd9,
0xb8, 0x6a, 0xfc, 0x3a, 0xae, 0x1a, 0x7f, 0x8c, 0xab, 0xc6, 0x5e, 0x41, 0xe5, 0xe7, 0xbd, 0xbf,
0x03, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x7d, 0xca, 0x6a, 0x9f, 0x11, 0x00, 0x00,
}

View file

@ -328,9 +328,7 @@ message Cluster {
}
// Secret represents a secret that should be passed to a container or a node,
// and is immutable. It wraps the `spec` provided by the user with useful
// information that is generated from the secret data in the `spec`, such as
// the digest and size of the secret data.
// and is immutable.
message Secret {
option (docker.protobuf.plugin.store_object) = {
watch_selectors: {
@ -355,6 +353,29 @@ message Secret {
bool internal = 4;
}
// Config represents a set of configuration files that should be passed to a
// container.
message Config {
option (docker.protobuf.plugin.store_object) = {
watch_selectors: {
id: true
id_prefix: true
name: true
name_prefix: true
custom: true
custom_prefix: true
}
};
string id = 1;
Meta meta = 2 [(gogoproto.nullable) = false];
// Spec contains the actual config data, as well as any context around the
// config data that the user provides.
ConfigSpec spec = 3 [(gogoproto.nullable) = false];
}
// Resource is a top-level object with externally defined content and indexing.
// SwarmKit can serve as a store for these objects without understanding their
// meanings.

View file

@ -175,6 +175,7 @@ type StoreAction struct {
// *StoreAction_Secret
// *StoreAction_Resource
// *StoreAction_Extension
// *StoreAction_Config
Target isStoreAction_Target `protobuf_oneof:"target"`
}
@ -212,6 +213,9 @@ type StoreAction_Resource struct {
type StoreAction_Extension struct {
Extension *Extension `protobuf:"bytes,9,opt,name=extension,oneof"`
}
type StoreAction_Config struct {
Config *Config `protobuf:"bytes,10,opt,name=config,oneof"`
}
func (*StoreAction_Node) isStoreAction_Target() {}
func (*StoreAction_Service) isStoreAction_Target() {}
@ -221,6 +225,7 @@ func (*StoreAction_Cluster) isStoreAction_Target() {}
func (*StoreAction_Secret) isStoreAction_Target() {}
func (*StoreAction_Resource) isStoreAction_Target() {}
func (*StoreAction_Extension) isStoreAction_Target() {}
func (*StoreAction_Config) isStoreAction_Target() {}
func (m *StoreAction) GetTarget() isStoreAction_Target {
if m != nil {
@ -285,6 +290,13 @@ func (m *StoreAction) GetExtension() *Extension {
return nil
}
func (m *StoreAction) GetConfig() *Config {
if x, ok := m.GetTarget().(*StoreAction_Config); ok {
return x.Config
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
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{}) {
return _StoreAction_OneofMarshaler, _StoreAction_OneofUnmarshaler, _StoreAction_OneofSizer, []interface{}{
@ -296,6 +308,7 @@ func (*StoreAction) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) e
(*StoreAction_Secret)(nil),
(*StoreAction_Resource)(nil),
(*StoreAction_Extension)(nil),
(*StoreAction_Config)(nil),
}
}
@ -343,6 +356,11 @@ func _StoreAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if err := b.EncodeMessage(x.Extension); err != nil {
return err
}
case *StoreAction_Config:
_ = b.EncodeVarint(10<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Config); err != nil {
return err
}
case nil:
default:
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
err := b.DecodeMessage(msg)
m.Target = &StoreAction_Extension{msg}
return true, err
case 10: // target.config
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Config)
err := b.DecodeMessage(msg)
m.Target = &StoreAction_Config{msg}
return true, err
default:
return false, nil
}
@ -466,6 +492,11 @@ func _StoreAction_OneofSizer(msg proto.Message) (n int) {
n += proto.SizeVarint(9<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *StoreAction_Config:
s := proto.Size(x.Config)
n += proto.SizeVarint(10<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
@ -757,6 +788,12 @@ func (m *StoreAction) CopyFrom(src interface{}) {
}
github_com_docker_swarmkit_api_deepcopy.Copy(v.Extension, o.GetExtension())
m.Target = &v
case *StoreAction_Config:
v := StoreAction_Config{
Config: &Config{},
}
github_com_docker_swarmkit_api_deepcopy.Copy(v.Config, o.GetConfig())
m.Target = &v
}
}
@ -1409,6 +1446,20 @@ func (m *StoreAction_Extension) MarshalTo(dAtA []byte) (int, error) {
}
return i, nil
}
func (m *StoreAction_Config) MarshalTo(dAtA []byte) (int, error) {
i := 0
if m.Config != nil {
dAtA[i] = 0x52
i++
i = encodeVarintRaft(dAtA, i, uint64(m.Config.Size()))
n15, err := m.Config.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n15
}
return i, nil
}
func encodeFixed64Raft(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
@ -1922,6 +1973,15 @@ func (m *StoreAction_Extension) Size() (n int) {
}
return n
}
func (m *StoreAction_Config) Size() (n int) {
var l int
_ = l
if m.Config != nil {
l = m.Config.Size()
n += 1 + l + sovRaft(uint64(l))
}
return n
}
func sovRaft(x uint64) (n int) {
for {
@ -2131,6 +2191,16 @@ func (this *StoreAction_Extension) String() string {
}, "")
return s
}
func (this *StoreAction_Config) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&StoreAction_Config{`,
`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
`}`,
}, "")
return s
}
func valueToStringRaft(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@ -3355,6 +3425,38 @@ func (m *StoreAction) Unmarshal(dAtA []byte) error {
}
m.Target = &StoreAction_Extension{v}
iNdEx = postIndex
case 10:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRaft
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &Config{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Target = &StoreAction_Config{v}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRaft(dAtA[iNdEx:])
@ -3484,64 +3586,65 @@ var (
func init() { proto.RegisterFile("raft.proto", fileDescriptorRaft) }
var fileDescriptorRaft = []byte{
// 933 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x96, 0x41, 0x73, 0xdb, 0x44,
0x14, 0xc7, 0x25, 0x5b, 0xb5, 0x9b, 0xe7, 0x26, 0xce, 0x6c, 0x48, 0x50, 0x45, 0x51, 0x5c, 0x95,
0x99, 0xba, 0x1d, 0x22, 0x0f, 0x86, 0x19, 0x98, 0x42, 0x0f, 0x71, 0xe2, 0x19, 0x9b, 0xb6, 0x4e,
0x47, 0x49, 0xa0, 0xb7, 0x20, 0x4b, 0x5b, 0x57, 0xd8, 0xd6, 0x9a, 0xdd, 0xb5, 0x03, 0x17, 0xa6,
0x47, 0x26, 0x27, 0x66, 0x98, 0x01, 0x2e, 0x3d, 0xc1, 0xb9, 0x1f, 0x80, 0x4f, 0x90, 0xe1, 0xc4,
0x0d, 0x4e, 0x19, 0xea, 0x0f, 0x00, 0x5f, 0x81, 0xd9, 0x95, 0x64, 0x07, 0x47, 0x76, 0x73, 0xb1,
0xd7, 0xbb, 0xbf, 0xff, 0xfb, 0xef, 0xee, 0xd3, 0x7b, 0x32, 0x00, 0x75, 0x9f, 0x72, 0x7b, 0x40,
0x09, 0x27, 0x08, 0xf9, 0xc4, 0xeb, 0x62, 0x6a, 0xb3, 0x63, 0x97, 0xf6, 0xbb, 0x01, 0xb7, 0x47,
0xef, 0x19, 0xcb, 0xa4, 0xfd, 0x25, 0xf6, 0x38, 0x8b, 0x10, 0xa3, 0xc0, 0xbf, 0x19, 0xe0, 0xe4,
0xc7, 0x56, 0x27, 0xe0, 0xcf, 0x86, 0x6d, 0xdb, 0x23, 0xfd, 0x8a, 0x47, 0x28, 0x26, 0xac, 0x82,
0xb9, 0xe7, 0x57, 0x44, 0x48, 0xf9, 0x31, 0x68, 0x57, 0xa6, 0xe1, 0x8d, 0x37, 0x3a, 0xa4, 0x43,
0xe4, 0xb0, 0x22, 0x46, 0xf1, 0xec, 0xda, 0xa0, 0x37, 0xec, 0x04, 0x61, 0x25, 0xfa, 0x8a, 0x26,
0xad, 0x97, 0x2a, 0x80, 0xe3, 0x3e, 0xe5, 0x8f, 0x70, 0xbf, 0x8d, 0x29, 0xba, 0x05, 0x79, 0x11,
0xe7, 0x28, 0xf0, 0x75, 0xb5, 0xa4, 0x96, 0xb5, 0x1a, 0x8c, 0xcf, 0x36, 0x73, 0x02, 0x68, 0xee,
0x3a, 0x39, 0xb1, 0xd4, 0xf4, 0x05, 0x14, 0x12, 0x1f, 0x0b, 0x28, 0x53, 0x52, 0xcb, 0x4b, 0x11,
0xd4, 0x22, 0x3e, 0x16, 0x90, 0x58, 0x6a, 0xfa, 0x08, 0x81, 0xe6, 0xfa, 0x3e, 0xd5, 0xb3, 0x82,
0x70, 0xe4, 0x18, 0xd5, 0x20, 0xc7, 0xb8, 0xcb, 0x87, 0x4c, 0xd7, 0x4a, 0x6a, 0xb9, 0x50, 0x7d,
0xc7, 0xbe, 0x78, 0x0f, 0xf6, 0x74, 0x37, 0xfb, 0x92, 0xad, 0x69, 0xa7, 0x67, 0x9b, 0x8a, 0x13,
0x2b, 0xad, 0x9b, 0x50, 0xf8, 0x94, 0x04, 0xa1, 0x83, 0xbf, 0x1a, 0x62, 0xc6, 0x27, 0x36, 0xea,
0xd4, 0xc6, 0xfa, 0x51, 0x85, 0x6b, 0x11, 0xc3, 0x06, 0x24, 0x64, 0xf8, 0x72, 0xa7, 0xfa, 0x08,
0xf2, 0x7d, 0x69, 0xcb, 0xf4, 0x4c, 0x29, 0x5b, 0x2e, 0x54, 0xcd, 0xc5, 0xbb, 0x73, 0x12, 0x1c,
0xdd, 0x86, 0x22, 0xc5, 0x7d, 0x32, 0xc2, 0xfe, 0x51, 0x12, 0x21, 0x5b, 0xca, 0x96, 0x35, 0x67,
0x25, 0x9e, 0x8e, 0x04, 0xcc, 0xaa, 0xc1, 0xb5, 0x87, 0xd8, 0x1d, 0xe1, 0x64, 0xf3, 0x55, 0xd0,
0xc4, 0x6d, 0xc9, 0x4d, 0xbd, 0xde, 0x4f, 0xb2, 0x56, 0x11, 0x96, 0xe3, 0x18, 0xd1, 0xe1, 0xac,
0x87, 0x70, 0xfd, 0x31, 0x25, 0x1e, 0x66, 0x2c, 0x62, 0x19, 0x73, 0x3b, 0x13, 0x87, 0x3b, 0xe2,
0x50, 0x72, 0x26, 0x36, 0x29, 0xda, 0xd1, 0xe3, 0x62, 0x27, 0x60, 0xb2, 0x7e, 0x4f, 0x7b, 0xfe,
0x93, 0xa5, 0x58, 0x37, 0xc0, 0x48, 0x8b, 0x16, 0x7b, 0x7d, 0x02, 0xeb, 0x0e, 0x66, 0xa4, 0x37,
0xc2, 0xdb, 0xbe, 0x4f, 0x05, 0x14, 0xfb, 0x5c, 0xe6, 0x86, 0xad, 0x77, 0x61, 0x63, 0x56, 0x1d,
0x27, 0x28, 0x2d, 0x8b, 0x3d, 0x58, 0x6b, 0x86, 0x1c, 0xd3, 0xd0, 0xed, 0x89, 0x38, 0x89, 0xd3,
0x06, 0x64, 0x26, 0x26, 0xb9, 0xf1, 0xd9, 0x66, 0xa6, 0xb9, 0xeb, 0x64, 0x02, 0x1f, 0xdd, 0x87,
0x9c, 0xeb, 0xf1, 0x80, 0x84, 0x71, 0xf6, 0x36, 0xd3, 0x6e, 0x73, 0x9f, 0x13, 0x8a, 0xb7, 0x25,
0x96, 0x3c, 0x56, 0x91, 0xc8, 0xfa, 0x5e, 0x83, 0xc2, 0xb9, 0x55, 0xf4, 0xf1, 0x24, 0x9c, 0xb0,
0x5a, 0xa9, 0xde, 0x7a, 0x4d, 0xb8, 0x07, 0x41, 0xe8, 0x27, 0xc1, 0x90, 0x1d, 0xe7, 0x35, 0x23,
0xaf, 0x5c, 0x4f, 0x93, 0x8a, 0x6a, 0x69, 0x28, 0x51, 0x4e, 0xd1, 0x87, 0x90, 0x67, 0x98, 0x8e,
0x02, 0x0f, 0xcb, 0x72, 0x29, 0x54, 0xdf, 0x4a, 0x75, 0x8b, 0x90, 0x86, 0xe2, 0x24, 0xb4, 0x30,
0xe2, 0x2e, 0xeb, 0xc6, 0xe5, 0x94, 0x6a, 0x74, 0xe0, 0xb2, 0xae, 0x30, 0x12, 0x9c, 0x30, 0x0a,
0x31, 0x3f, 0x26, 0xb4, 0xab, 0x5f, 0x99, 0x6f, 0xd4, 0x8a, 0x10, 0x61, 0x14, 0xd3, 0x42, 0xe8,
0xf5, 0x86, 0x8c, 0x63, 0xaa, 0xe7, 0xe6, 0x0b, 0x77, 0x22, 0x44, 0x08, 0x63, 0x1a, 0x7d, 0x00,
0x39, 0x86, 0x3d, 0x8a, 0xb9, 0x9e, 0x97, 0x3a, 0x23, 0xfd, 0x64, 0x82, 0x68, 0x88, 0x22, 0x97,
0x23, 0x74, 0x0f, 0xae, 0x52, 0xcc, 0xc8, 0x90, 0x7a, 0x58, 0xbf, 0x2a, 0x75, 0x37, 0x52, 0x8b,
0x23, 0x66, 0x1a, 0x8a, 0x33, 0xe1, 0xd1, 0x7d, 0x58, 0xc2, 0x5f, 0x73, 0x1c, 0x32, 0x91, 0xbc,
0x25, 0x29, 0x7e, 0x3b, 0x4d, 0x5c, 0x4f, 0xa0, 0x86, 0xe2, 0x4c, 0x15, 0xb5, 0xab, 0x90, 0xe3,
0x2e, 0xed, 0x60, 0x7e, 0xf7, 0x5f, 0x15, 0x8a, 0x33, 0x19, 0x46, 0xb7, 0x21, 0x7f, 0xd8, 0x7a,
0xd0, 0xda, 0xfb, 0xbc, 0xb5, 0xaa, 0x18, 0xc6, 0xc9, 0x8b, 0xd2, 0xc6, 0x0c, 0x71, 0x18, 0x76,
0x43, 0x72, 0x1c, 0xa2, 0x2a, 0xac, 0xed, 0x1f, 0xec, 0x39, 0xf5, 0xa3, 0xed, 0x9d, 0x83, 0xe6,
0x5e, 0xeb, 0x68, 0xc7, 0xa9, 0x6f, 0x1f, 0xd4, 0x57, 0x55, 0xe3, 0xfa, 0xc9, 0x8b, 0xd2, 0xfa,
0x8c, 0x68, 0x87, 0x62, 0x97, 0xe3, 0x0b, 0x9a, 0xc3, 0xc7, 0xbb, 0x42, 0x93, 0x49, 0xd5, 0x1c,
0x0e, 0xfc, 0x34, 0x8d, 0x53, 0x7f, 0xb4, 0xf7, 0x59, 0x7d, 0x35, 0x9b, 0xaa, 0x71, 0x64, 0x3b,
0x32, 0xde, 0xfc, 0xee, 0x17, 0x53, 0xf9, 0xed, 0x57, 0x73, 0xf6, 0x74, 0xd5, 0x1f, 0x32, 0xa0,
0x89, 0x5a, 0x43, 0x27, 0x2a, 0xa0, 0x8b, 0x6d, 0x00, 0x6d, 0xa5, 0xdd, 0xe3, 0xdc, 0xe6, 0x63,
0xd8, 0x97, 0xc5, 0xe3, 0xee, 0xb2, 0xfe, 0xfb, 0xcb, 0x7f, 0x7e, 0xce, 0x14, 0x61, 0x59, 0xf2,
0x5b, 0x7d, 0x37, 0x74, 0x3b, 0x98, 0xa2, 0x6f, 0x61, 0xe5, 0xff, 0x6d, 0x03, 0xdd, 0x99, 0xf7,
0x30, 0x5c, 0x68, 0x4c, 0xc6, 0xdd, 0xcb, 0xa0, 0x0b, 0xfd, 0xab, 0x7f, 0xaa, 0xb0, 0x32, 0x6d,
0xc3, 0xec, 0x59, 0x30, 0x40, 0x5f, 0x80, 0x26, 0x5e, 0x30, 0x28, 0xb5, 0xc9, 0x9c, 0x7b, 0x3d,
0x19, 0xa5, 0xf9, 0xc0, 0xe2, 0x43, 0x7b, 0x70, 0x45, 0xb6, 0x79, 0x94, 0x1a, 0xe1, 0xfc, 0x5b,
0xc4, 0xb8, 0xb9, 0x80, 0x58, 0x68, 0x52, 0xd3, 0x4f, 0x5f, 0x99, 0xca, 0x5f, 0xaf, 0x4c, 0xe5,
0xf9, 0xd8, 0x54, 0x4f, 0xc7, 0xa6, 0xfa, 0xc7, 0xd8, 0x54, 0xff, 0x1e, 0x9b, 0xea, 0x93, 0xec,
0x13, 0xad, 0x9d, 0x93, 0xff, 0x10, 0xde, 0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x98, 0x55, 0x8d,
0x81, 0xb9, 0x08, 0x00, 0x00,
// 949 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x96, 0x4f, 0x6f, 0x1b, 0x45,
0x18, 0xc6, 0x77, 0xed, 0xad, 0x9d, 0xbc, 0x6e, 0xe2, 0x68, 0x42, 0xc2, 0x76, 0x29, 0x8e, 0xbb,
0x45, 0xaa, 0x5b, 0x91, 0xb5, 0x30, 0x48, 0xa0, 0x42, 0x0f, 0xb1, 0x63, 0xc9, 0xa6, 0xad, 0x53,
0x6d, 0x12, 0xe8, 0x2d, 0xac, 0x77, 0x27, 0xee, 0x62, 0x7b, 0xc7, 0xcc, 0x8c, 0x1d, 0xb8, 0xa0,
0x1e, 0x51, 0xae, 0x48, 0xc0, 0xa5, 0x27, 0x38, 0xf7, 0x03, 0xf0, 0x01, 0x50, 0xc4, 0x89, 0x1b,
0x9c, 0x22, 0xea, 0x0f, 0x00, 0x5f, 0x01, 0xcd, 0xec, 0xae, 0x1d, 0x9c, 0xb5, 0x9b, 0x8b, 0x3d,
0x9e, 0xf9, 0x3d, 0xef, 0xf3, 0xce, 0xbf, 0x77, 0x0c, 0x40, 0x9d, 0x63, 0x6e, 0x0d, 0x28, 0xe1,
0x04, 0x21, 0x8f, 0xb8, 0x5d, 0x4c, 0x2d, 0x76, 0xe2, 0xd0, 0x7e, 0xd7, 0xe7, 0xd6, 0xe8, 0x3d,
0x63, 0x85, 0xb4, 0xbf, 0xc4, 0x2e, 0x67, 0x21, 0x62, 0xe4, 0xf8, 0x37, 0x03, 0x1c, 0xff, 0xd8,
0xee, 0xf8, 0xfc, 0xd9, 0xb0, 0x6d, 0xb9, 0xa4, 0x5f, 0x76, 0x09, 0xc5, 0x84, 0x95, 0x31, 0x77,
0xbd, 0xb2, 0x08, 0x29, 0x3f, 0x06, 0xed, 0xf2, 0x34, 0xbc, 0xf1, 0x46, 0x87, 0x74, 0x88, 0x6c,
0x96, 0x45, 0x2b, 0xea, 0x5d, 0x1f, 0xf4, 0x86, 0x1d, 0x3f, 0x28, 0x87, 0x5f, 0x61, 0xa7, 0xf9,
0x52, 0x05, 0xb0, 0x9d, 0x63, 0xfe, 0x18, 0xf7, 0xdb, 0x98, 0xa2, 0xdb, 0x90, 0x15, 0x71, 0x8e,
0x7c, 0x4f, 0x57, 0x8b, 0x6a, 0x49, 0xab, 0xc2, 0xf8, 0x7c, 0x2b, 0x23, 0x80, 0xe6, 0xae, 0x9d,
0x11, 0x43, 0x4d, 0x4f, 0x40, 0x01, 0xf1, 0xb0, 0x80, 0x52, 0x45, 0xb5, 0xb4, 0x1c, 0x42, 0x2d,
0xe2, 0x61, 0x01, 0x89, 0xa1, 0xa6, 0x87, 0x10, 0x68, 0x8e, 0xe7, 0x51, 0x3d, 0x2d, 0x08, 0x5b,
0xb6, 0x51, 0x15, 0x32, 0x8c, 0x3b, 0x7c, 0xc8, 0x74, 0xad, 0xa8, 0x96, 0x72, 0x95, 0x77, 0xac,
0xcb, 0xeb, 0x60, 0x4d, 0xb3, 0xd9, 0x97, 0x6c, 0x55, 0x3b, 0x3b, 0xdf, 0x52, 0xec, 0x48, 0x69,
0xde, 0x82, 0xdc, 0xa7, 0xc4, 0x0f, 0x6c, 0xfc, 0xd5, 0x10, 0x33, 0x3e, 0xb1, 0x51, 0xa7, 0x36,
0xe6, 0x0f, 0x2a, 0x5c, 0x0f, 0x19, 0x36, 0x20, 0x01, 0xc3, 0x57, 0x9b, 0xd5, 0x47, 0x90, 0xed,
0x4b, 0x5b, 0xa6, 0xa7, 0x8a, 0xe9, 0x52, 0xae, 0x52, 0x58, 0x9c, 0x9d, 0x1d, 0xe3, 0xe8, 0x0e,
0xe4, 0x29, 0xee, 0x93, 0x11, 0xf6, 0x8e, 0xe2, 0x08, 0xe9, 0x62, 0xba, 0xa4, 0xd9, 0xab, 0x51,
0x77, 0x28, 0x60, 0x66, 0x15, 0xae, 0x3f, 0xc2, 0xce, 0x08, 0xc7, 0xc9, 0x57, 0x40, 0x13, 0xab,
0x25, 0x93, 0x7a, 0xbd, 0x9f, 0x64, 0xcd, 0x3c, 0xac, 0x44, 0x31, 0xc2, 0xc9, 0x99, 0x8f, 0xe0,
0xc6, 0x13, 0x4a, 0x5c, 0xcc, 0x58, 0xc8, 0x32, 0xe6, 0x74, 0x26, 0x0e, 0x77, 0xc5, 0xa4, 0x64,
0x4f, 0x64, 0x92, 0xb7, 0xc2, 0xe3, 0x62, 0xc5, 0x60, 0x3c, 0x7e, 0x5f, 0x7b, 0xfe, 0xa3, 0xa9,
0x98, 0x37, 0xc1, 0x48, 0x8a, 0x16, 0x79, 0x7d, 0x02, 0x1b, 0x36, 0x66, 0xa4, 0x37, 0xc2, 0x3b,
0x9e, 0x47, 0x05, 0x14, 0xf9, 0x5c, 0x65, 0x85, 0xcd, 0x77, 0x61, 0x73, 0x56, 0x1d, 0x6d, 0x50,
0xd2, 0x2e, 0xf6, 0x60, 0xbd, 0x19, 0x70, 0x4c, 0x03, 0xa7, 0x27, 0xe2, 0xc4, 0x4e, 0x9b, 0x90,
0x9a, 0x98, 0x64, 0xc6, 0xe7, 0x5b, 0xa9, 0xe6, 0xae, 0x9d, 0xf2, 0x3d, 0xf4, 0x00, 0x32, 0x8e,
0xcb, 0x7d, 0x12, 0x44, 0xbb, 0xb7, 0x95, 0xb4, 0x9a, 0xfb, 0x9c, 0x50, 0xbc, 0x23, 0xb1, 0xf8,
0x58, 0x85, 0x22, 0xf3, 0x37, 0x0d, 0x72, 0x17, 0x46, 0xd1, 0xc7, 0x93, 0x70, 0xc2, 0x6a, 0xb5,
0x72, 0xfb, 0x35, 0xe1, 0x1e, 0xfa, 0x81, 0x17, 0x07, 0x43, 0x56, 0xb4, 0xaf, 0x29, 0xb9, 0xe4,
0x7a, 0x92, 0x54, 0xdc, 0x96, 0x86, 0x12, 0xee, 0x29, 0xfa, 0x10, 0xb2, 0x0c, 0xd3, 0x91, 0xef,
0x62, 0x79, 0x5d, 0x72, 0x95, 0xb7, 0x12, 0xdd, 0x42, 0xa4, 0xa1, 0xd8, 0x31, 0x2d, 0x8c, 0xb8,
0xc3, 0xba, 0xd1, 0x75, 0x4a, 0x34, 0x3a, 0x70, 0x58, 0x57, 0x18, 0x09, 0x4e, 0x18, 0x05, 0x98,
0x9f, 0x10, 0xda, 0xd5, 0xaf, 0xcd, 0x37, 0x6a, 0x85, 0x88, 0x30, 0x8a, 0x68, 0x21, 0x74, 0x7b,
0x43, 0xc6, 0x31, 0xd5, 0x33, 0xf3, 0x85, 0xb5, 0x10, 0x11, 0xc2, 0x88, 0x46, 0x1f, 0x40, 0x86,
0x61, 0x97, 0x62, 0xae, 0x67, 0xa5, 0xce, 0x48, 0x9e, 0x99, 0x20, 0x1a, 0xe2, 0x92, 0xcb, 0x16,
0xba, 0x0f, 0x4b, 0x14, 0x33, 0x32, 0xa4, 0x2e, 0xd6, 0x97, 0xa4, 0xee, 0x66, 0xe2, 0xe5, 0x88,
0x98, 0x86, 0x62, 0x4f, 0x78, 0xf4, 0x00, 0x96, 0xf1, 0xd7, 0x1c, 0x07, 0x4c, 0x6c, 0xde, 0xb2,
0x14, 0xbf, 0x9d, 0x24, 0xae, 0xc7, 0x50, 0x43, 0xb1, 0xa7, 0x0a, 0x91, 0xb0, 0x4b, 0x82, 0x63,
0xbf, 0xa3, 0xc3, 0xfc, 0x84, 0x6b, 0x92, 0x10, 0x09, 0x87, 0x6c, 0x75, 0x09, 0x32, 0xdc, 0xa1,
0x1d, 0xcc, 0xef, 0xfd, 0xab, 0x42, 0x7e, 0xe6, 0x5c, 0xa0, 0x3b, 0x90, 0x3d, 0x6c, 0x3d, 0x6c,
0xed, 0x7d, 0xde, 0x5a, 0x53, 0x0c, 0xe3, 0xf4, 0x45, 0x71, 0x73, 0x86, 0x38, 0x0c, 0xba, 0x01,
0x39, 0x09, 0x50, 0x05, 0xd6, 0xf7, 0x0f, 0xf6, 0xec, 0xfa, 0xd1, 0x4e, 0xed, 0xa0, 0xb9, 0xd7,
0x3a, 0xaa, 0xd9, 0xf5, 0x9d, 0x83, 0xfa, 0x9a, 0x6a, 0xdc, 0x38, 0x7d, 0x51, 0xdc, 0x98, 0x11,
0xd5, 0x28, 0x76, 0x38, 0xbe, 0xa4, 0x39, 0x7c, 0xb2, 0x2b, 0x34, 0xa9, 0x44, 0xcd, 0xe1, 0xc0,
0x4b, 0xd2, 0xd8, 0xf5, 0xc7, 0x7b, 0x9f, 0xd5, 0xd7, 0xd2, 0x89, 0x1a, 0x5b, 0x16, 0x31, 0xe3,
0xcd, 0xef, 0x7e, 0x2e, 0x28, 0xbf, 0xfe, 0x52, 0x98, 0x9d, 0x5d, 0xe5, 0xfb, 0x14, 0x68, 0xe2,
0x86, 0xa2, 0x53, 0x15, 0xd0, 0xe5, 0xe2, 0x81, 0xb6, 0x93, 0x56, 0x70, 0x6e, 0xc9, 0x32, 0xac,
0xab, 0xe2, 0x51, 0x4d, 0xda, 0xf8, 0xfd, 0xe5, 0x3f, 0x3f, 0xa5, 0xf2, 0xb0, 0x22, 0xf9, 0xed,
0xbe, 0x13, 0x38, 0x1d, 0x4c, 0xd1, 0xb7, 0xb0, 0xfa, 0xff, 0x62, 0x83, 0xee, 0xce, 0x3b, 0x42,
0x97, 0xca, 0x99, 0x71, 0xef, 0x2a, 0xe8, 0x42, 0xff, 0xca, 0x9f, 0x2a, 0xac, 0x4e, 0x8b, 0x37,
0x7b, 0xe6, 0x0f, 0xd0, 0x17, 0xa0, 0x89, 0x67, 0x09, 0x25, 0x96, 0xa6, 0x0b, 0x8f, 0x9a, 0x51,
0x9c, 0x0f, 0x2c, 0x9e, 0xb4, 0x0b, 0xd7, 0xe4, 0xe3, 0x80, 0x12, 0x23, 0x5c, 0x7c, 0x7b, 0x8c,
0x5b, 0x0b, 0x88, 0x85, 0x26, 0x55, 0xfd, 0xec, 0x55, 0x41, 0xf9, 0xeb, 0x55, 0x41, 0x79, 0x3e,
0x2e, 0xa8, 0x67, 0xe3, 0x82, 0xfa, 0xc7, 0xb8, 0xa0, 0xfe, 0x3d, 0x2e, 0xa8, 0x4f, 0xd3, 0x4f,
0xb5, 0x76, 0x46, 0xfe, 0xaf, 0x78, 0xff, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x31, 0xfd,
0xe7, 0xef, 0x08, 0x00, 0x00,
}

View file

@ -127,5 +127,6 @@ message StoreAction {
Secret secret = 7;
Resource resource = 8;
Extension extension = 9;
Config config = 10;
}
}

View file

@ -51,6 +51,7 @@ type StoreSnapshot struct {
Secrets []*Secret `protobuf:"bytes,6,rep,name=secrets" json:"secrets,omitempty"`
Resources []*Resource `protobuf:"bytes,7,rep,name=resources" json:"resources,omitempty"`
Extensions []*Extension `protobuf:"bytes,8,rep,name=extensions" json:"extensions,omitempty"`
Configs []*Config `protobuf:"bytes,9,rep,name=configs" json:"configs,omitempty"`
}
func (m *StoreSnapshot) Reset() { *m = StoreSnapshot{} }
@ -161,6 +162,14 @@ func (m *StoreSnapshot) CopyFrom(src interface{}) {
}
}
if o.Configs != nil {
m.Configs = make([]*Config, len(o.Configs))
for i := range m.Configs {
m.Configs[i] = &Config{}
github_com_docker_swarmkit_api_deepcopy.Copy(m.Configs[i], o.Configs[i])
}
}
}
func (m *ClusterSnapshot) Copy() *ClusterSnapshot {
@ -319,6 +328,18 @@ func (m *StoreSnapshot) MarshalTo(dAtA []byte) (int, error) {
i += n
}
}
if len(m.Configs) > 0 {
for _, msg := range m.Configs {
dAtA[i] = 0x4a
i++
i = encodeVarintSnapshot(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
@ -487,6 +508,12 @@ func (m *StoreSnapshot) Size() (n int) {
n += 1 + l + sovSnapshot(uint64(l))
}
}
if len(m.Configs) > 0 {
for _, e := range m.Configs {
l = e.Size()
n += 1 + l + sovSnapshot(uint64(l))
}
}
return n
}
@ -548,6 +575,7 @@ func (this *StoreSnapshot) String() string {
`Secrets:` + strings.Replace(fmt.Sprintf("%v", this.Secrets), "Secret", "Secret", 1) + `,`,
`Resources:` + strings.Replace(fmt.Sprintf("%v", this.Resources), "Resource", "Resource", 1) + `,`,
`Extensions:` + strings.Replace(fmt.Sprintf("%v", this.Extensions), "Extension", "Extension", 1) + `,`,
`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "Config", "Config", 1) + `,`,
`}`,
}, "")
return s
@ -860,6 +888,37 @@ func (m *StoreSnapshot) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Configs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSnapshot
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthSnapshot
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Configs = append(m.Configs, &Config{})
if err := m.Configs[len(m.Configs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipSnapshot(dAtA[iNdEx:])
@ -1261,34 +1320,35 @@ var (
func init() { proto.RegisterFile("snapshot.proto", fileDescriptorSnapshot) }
var fileDescriptorSnapshot = []byte{
// 449 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x93, 0xbf, 0x6f, 0xd3, 0x40,
0x14, 0xc7, 0x73, 0xf9, 0xe5, 0xf0, 0xaa, 0x16, 0x38, 0x31, 0x9c, 0x02, 0x98, 0x10, 0x18, 0x32,
0x19, 0x08, 0x48, 0x20, 0xa4, 0x32, 0x14, 0x31, 0x30, 0xd0, 0xe1, 0x82, 0x2a, 0x56, 0xc7, 0x79,
0x6d, 0x83, 0x89, 0x2f, 0xba, 0x77, 0x75, 0x19, 0xf9, 0xf3, 0x22, 0xb1, 0x30, 0x32, 0x21, 0xea,
0x85, 0x7f, 0x03, 0xdd, 0x9d, 0x6d, 0x22, 0xe1, 0x74, 0xbb, 0x44, 0x9f, 0xcf, 0xfb, 0xbe, 0xbb,
0xf7, 0x0c, 0x07, 0x94, 0xc5, 0x6b, 0x3a, 0x57, 0x26, 0x5a, 0x6b, 0x65, 0x14, 0xe7, 0x0b, 0x95,
0xa4, 0xa8, 0x23, 0xba, 0x8c, 0xf5, 0x2a, 0x5d, 0x9a, 0x28, 0x7f, 0x36, 0xdc, 0x57, 0xf3, 0xcf,
0x98, 0x18, 0xf2, 0xc8, 0x10, 0x74, 0x7c, 0x5a, 0xe2, 0xc3, 0x3b, 0x67, 0xea, 0x4c, 0xb9, 0xe3,
0x13, 0x7b, 0xf2, 0xff, 0x8e, 0xbf, 0x77, 0x60, 0x7f, 0x66, 0x94, 0xc6, 0x59, 0x59, 0x9c, 0x47,
0xd0, 0xcb, 0xd4, 0x02, 0x49, 0xb0, 0x51, 0x67, 0xb2, 0x37, 0x15, 0xd1, 0xff, 0x31, 0xd1, 0xb1,
0x5a, 0xa0, 0xf4, 0x18, 0x7f, 0x09, 0x03, 0x42, 0x9d, 0x2f, 0x13, 0x24, 0xd1, 0x76, 0xca, 0xdd,
0x26, 0x65, 0xe6, 0x19, 0x59, 0xc3, 0x56, 0xcc, 0xd0, 0x5c, 0x2a, 0x9d, 0x92, 0xe8, 0xec, 0x16,
0x8f, 0x3d, 0x23, 0x6b, 0xd8, 0x76, 0x68, 0x62, 0x4a, 0x49, 0x74, 0x77, 0x77, 0xf8, 0x31, 0xa6,
0x54, 0x7a, 0xcc, 0x06, 0x25, 0x5f, 0x2e, 0xc8, 0xa0, 0x26, 0xd1, 0xdb, 0x1d, 0xf4, 0xd6, 0x33,
0xb2, 0x86, 0xf9, 0x0b, 0x08, 0x08, 0x13, 0x8d, 0x86, 0x44, 0xdf, 0x79, 0xc3, 0xe6, 0x9b, 0x59,
0x44, 0x56, 0x28, 0x7f, 0x0d, 0x37, 0x34, 0x92, 0xba, 0xd0, 0xf6, 0x45, 0x02, 0xe7, 0xdd, 0x6b,
0xf2, 0x64, 0x09, 0xc9, 0x7f, 0x38, 0x3f, 0x04, 0xc0, 0xaf, 0x06, 0x33, 0x5a, 0xaa, 0x8c, 0xc4,
0xc0, 0xc9, 0xf7, 0x9b, 0xe4, 0x77, 0x15, 0x25, 0xb7, 0x84, 0x31, 0xc2, 0xcd, 0xf2, 0x16, 0xf5,
0x38, 0x5f, 0x41, 0xb0, 0xc2, 0xd5, 0xdc, 0xde, 0xdd, 0x0f, 0x34, 0x6c, 0xec, 0x25, 0x3e, 0x35,
0x1f, 0x1c, 0x26, 0x2b, 0x9c, 0x0b, 0x08, 0x34, 0xae, 0x54, 0x8e, 0x0b, 0x37, 0xd7, 0xae, 0xac,
0x7e, 0x8e, 0xff, 0x30, 0x18, 0xd4, 0x01, 0x6f, 0x20, 0xc8, 0x51, 0xdb, 0x7c, 0xc1, 0x46, 0x6c,
0x72, 0x30, 0x7d, 0xdc, 0xf8, 0x48, 0xd5, 0xee, 0x9e, 0x78, 0x56, 0x56, 0x12, 0x7f, 0x0f, 0x50,
0x26, 0x9e, 0x2f, 0xd7, 0xa2, 0x3d, 0x62, 0x93, 0xbd, 0xe9, 0xa3, 0x6b, 0xe6, 0x53, 0x55, 0x3a,
0xea, 0x6e, 0x7e, 0x3d, 0x68, 0xc9, 0x2d, 0x99, 0x1f, 0x42, 0x8f, 0xec, 0x2e, 0x8b, 0x8e, 0xab,
0xf2, 0xb0, 0xb1, 0x91, 0xed, 0x65, 0x2f, 0x6b, 0x78, 0x6b, 0x7c, 0x1b, 0x82, 0xb2, 0x3b, 0xde,
0x87, 0xf6, 0xc9, 0xd3, 0x5b, 0xad, 0x23, 0xb1, 0xb9, 0x0a, 0x5b, 0x3f, 0xaf, 0xc2, 0xd6, 0xb7,
0x22, 0x64, 0x9b, 0x22, 0x64, 0x3f, 0x8a, 0x90, 0xfd, 0x2e, 0x42, 0xf6, 0xa9, 0x3d, 0xef, 0xbb,
0x2f, 0xe8, 0xf9, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x91, 0xfe, 0xed, 0x18, 0x98, 0x03, 0x00,
0x00,
// 466 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x93, 0x3f, 0x6f, 0x13, 0x4d,
0x10, 0x87, 0xbd, 0xfe, 0x77, 0xce, 0x44, 0xc9, 0xfb, 0xb2, 0xa2, 0x58, 0x19, 0x38, 0x8c, 0xa1,
0x70, 0x75, 0x80, 0x41, 0x02, 0x21, 0x85, 0x22, 0x11, 0x05, 0x05, 0x29, 0xd6, 0x28, 0xa2, 0x3d,
0x9f, 0xc7, 0xce, 0x71, 0xf8, 0xd6, 0xda, 0xd9, 0x38, 0x94, 0xf0, 0xed, 0x5c, 0x52, 0x52, 0x21,
0xe2, 0x86, 0xaf, 0x81, 0x76, 0xf7, 0xee, 0xb0, 0xc4, 0x99, 0x6e, 0x6d, 0x3d, 0xcf, 0xcc, 0x6f,
0xf7, 0x66, 0xe0, 0x98, 0xf2, 0x78, 0x45, 0x97, 0xca, 0x44, 0x2b, 0xad, 0x8c, 0xe2, 0x7c, 0xa6,
0x92, 0x0c, 0x75, 0x44, 0xd7, 0xb1, 0x5e, 0x66, 0xa9, 0x89, 0xd6, 0x4f, 0xfb, 0x47, 0x6a, 0xfa,
0x11, 0x13, 0x43, 0x1e, 0xe9, 0x83, 0x8e, 0xe7, 0x05, 0xde, 0xbf, 0xbd, 0x50, 0x0b, 0xe5, 0x8e,
0x8f, 0xed, 0xc9, 0xff, 0x3b, 0xfc, 0xda, 0x86, 0xa3, 0x89, 0x51, 0x1a, 0x27, 0x45, 0x71, 0x1e,
0x41, 0x27, 0x57, 0x33, 0x24, 0xc1, 0x06, 0xad, 0xd1, 0xe1, 0x58, 0x44, 0x7f, 0xb7, 0x89, 0xce,
0xd5, 0x0c, 0xa5, 0xc7, 0xf8, 0x0b, 0xe8, 0x11, 0xea, 0x75, 0x9a, 0x20, 0x89, 0xa6, 0x53, 0xee,
0xd4, 0x29, 0x13, 0xcf, 0xc8, 0x0a, 0xb6, 0x62, 0x8e, 0xe6, 0x5a, 0xe9, 0x8c, 0x44, 0x6b, 0xbf,
0x78, 0xee, 0x19, 0x59, 0xc1, 0x36, 0xa1, 0x89, 0x29, 0x23, 0xd1, 0xde, 0x9f, 0xf0, 0x7d, 0x4c,
0x99, 0xf4, 0x98, 0x6d, 0x94, 0x7c, 0xba, 0x22, 0x83, 0x9a, 0x44, 0x67, 0x7f, 0xa3, 0x33, 0xcf,
0xc8, 0x0a, 0xe6, 0xcf, 0x21, 0x20, 0x4c, 0x34, 0x1a, 0x12, 0x5d, 0xe7, 0xf5, 0xeb, 0x6f, 0x66,
0x11, 0x59, 0xa2, 0xfc, 0x15, 0x1c, 0x68, 0x24, 0x75, 0xa5, 0xed, 0x8b, 0x04, 0xce, 0xbb, 0x5b,
0xe7, 0xc9, 0x02, 0x92, 0x7f, 0x70, 0x7e, 0x02, 0x80, 0x9f, 0x0d, 0xe6, 0x94, 0xaa, 0x9c, 0x44,
0xcf, 0xc9, 0xf7, 0xea, 0xe4, 0x37, 0x25, 0x25, 0x77, 0x04, 0x1b, 0x38, 0x51, 0xf9, 0x3c, 0x5d,
0x90, 0x38, 0xd8, 0x1f, 0xf8, 0xcc, 0x21, 0xb2, 0x44, 0x87, 0x08, 0xff, 0x15, 0x77, 0xaf, 0x86,
0xe0, 0x25, 0x04, 0x4b, 0x5c, 0x4e, 0xed, 0x8b, 0xf9, 0x31, 0x08, 0x6b, 0x6f, 0x10, 0xcf, 0xcd,
0x3b, 0x87, 0xc9, 0x12, 0xe7, 0x02, 0x02, 0x8d, 0x4b, 0xb5, 0xc6, 0x99, 0x9b, 0x86, 0xb6, 0x2c,
0x7f, 0x0e, 0x7f, 0x31, 0xe8, 0x55, 0x0d, 0x5e, 0x43, 0xb0, 0x46, 0x6d, 0x53, 0x0b, 0x36, 0x60,
0xa3, 0xe3, 0xf1, 0xa3, 0xda, 0xa7, 0x2d, 0x27, 0xfe, 0xc2, 0xb3, 0xb2, 0x94, 0xf8, 0x5b, 0x80,
0xa2, 0xe3, 0x65, 0xba, 0x12, 0xcd, 0x01, 0x1b, 0x1d, 0x8e, 0x1f, 0xfe, 0xe3, 0xab, 0x96, 0x95,
0x4e, 0xdb, 0x9b, 0x1f, 0xf7, 0x1b, 0x72, 0x47, 0xe6, 0x27, 0xd0, 0x21, 0xbb, 0x01, 0xa2, 0xe5,
0xaa, 0x3c, 0xa8, 0x0d, 0xb2, 0xbb, 0x22, 0x45, 0x0d, 0x6f, 0x0d, 0x6f, 0x41, 0x50, 0xa4, 0xe3,
0x5d, 0x68, 0x5e, 0x3c, 0xf9, 0xbf, 0x71, 0x2a, 0x36, 0x37, 0x61, 0xe3, 0xfb, 0x4d, 0xd8, 0xf8,
0xb2, 0x0d, 0xd9, 0x66, 0x1b, 0xb2, 0x6f, 0xdb, 0x90, 0xfd, 0xdc, 0x86, 0xec, 0x43, 0x73, 0xda,
0x75, 0x7b, 0xf7, 0xec, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x41, 0x5b, 0x51, 0xce, 0x03,
0x00, 0x00,
}

View file

@ -22,6 +22,7 @@ message StoreSnapshot {
repeated Secret secrets = 6;
repeated Resource resources = 7;
repeated Extension extensions = 8;
repeated Config configs = 9;
}
// ClusterSnapshot stores cluster membership information in snapshots.

View file

@ -522,6 +522,8 @@ type ContainerSpec struct {
User string `protobuf:"bytes,7,opt,name=user,proto3" json:"user,omitempty"`
// Groups specifies supplementary groups available to the user.
Groups []string `protobuf:"bytes,11,rep,name=groups" json:"groups,omitempty"`
// Privileges specifies security configuration/permissions.
Privileges *Privileges `protobuf:"bytes,22,opt,name=privileges" json:"privileges,omitempty"`
// TTY declares that a TTY should be attached to the standard streams,
// including stdin if it is still open.
TTY bool `protobuf:"varint,13,opt,name=tty,proto3" json:"tty,omitempty"`
@ -544,6 +546,9 @@ type ContainerSpec struct {
// SecretReference contains references to zero or more secrets that
// will be exposed to the container.
Secrets []*SecretReference `protobuf:"bytes,12,rep,name=secrets" json:"secrets,omitempty"`
// ConfigReference contains references to zero or more configs that
// will be exposed to the container.
Configs []*ConfigReference `protobuf:"bytes,21,rep,name=configs" json:"configs,omitempty"`
// Hosts allow additional entries to be specified in /etc/hosts
// that associates IP addresses with hostnames.
// Detailed documentation is available in:
@ -679,6 +684,19 @@ func (m *SecretSpec) Reset() { *m = SecretSpec{} }
func (*SecretSpec) ProtoMessage() {}
func (*SecretSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{11} }
// ConfigSpec specifies user-provided configuration files.
type ConfigSpec struct {
Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"`
// Data is the config payload - the maximum size is 500KB (that is, 500*1024 bytes)
// TODO(aaronl): Do we want to revise this to include multiple payloads in a single
// ConfigSpec? Define this to be a tar? etc...
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *ConfigSpec) Reset() { *m = ConfigSpec{} }
func (*ConfigSpec) ProtoMessage() {}
func (*ConfigSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{12} }
func init() {
proto.RegisterType((*NodeSpec)(nil), "docker.swarmkit.v1.NodeSpec")
proto.RegisterType((*ServiceSpec)(nil), "docker.swarmkit.v1.ServiceSpec")
@ -694,6 +712,7 @@ func init() {
proto.RegisterType((*NetworkSpec)(nil), "docker.swarmkit.v1.NetworkSpec")
proto.RegisterType((*ClusterSpec)(nil), "docker.swarmkit.v1.ClusterSpec")
proto.RegisterType((*SecretSpec)(nil), "docker.swarmkit.v1.SecretSpec")
proto.RegisterType((*ConfigSpec)(nil), "docker.swarmkit.v1.ConfigSpec")
proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Membership", NodeSpec_Membership_name, NodeSpec_Membership_value)
proto.RegisterEnum("docker.swarmkit.v1.NodeSpec_Availability", NodeSpec_Availability_name, NodeSpec_Availability_value)
proto.RegisterEnum("docker.swarmkit.v1.EndpointSpec_ResolutionMode", EndpointSpec_ResolutionMode_name, EndpointSpec_ResolutionMode_value)
@ -930,6 +949,10 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
copy(m.Groups, o.Groups)
}
if o.Privileges != nil {
m.Privileges = &Privileges{}
github_com_docker_swarmkit_api_deepcopy.Copy(m.Privileges, o.Privileges)
}
if o.Mounts != nil {
m.Mounts = make([]Mount, len(o.Mounts))
for i := range m.Mounts {
@ -953,6 +976,14 @@ func (m *ContainerSpec) CopyFrom(src interface{}) {
}
}
if o.Configs != nil {
m.Configs = make([]*ConfigReference, len(o.Configs))
for i := range m.Configs {
m.Configs[i] = &ConfigReference{}
github_com_docker_swarmkit_api_deepcopy.Copy(m.Configs[i], o.Configs[i])
}
}
if o.Hosts != nil {
m.Hosts = make([]string, len(o.Hosts))
copy(m.Hosts, o.Hosts)
@ -1103,6 +1134,26 @@ func (m *SecretSpec) CopyFrom(src interface{}) {
}
}
func (m *ConfigSpec) Copy() *ConfigSpec {
if m == nil {
return nil
}
o := &ConfigSpec{}
o.CopyFrom(m)
return o
}
func (m *ConfigSpec) CopyFrom(src interface{}) {
o := src.(*ConfigSpec)
*m = *o
github_com_docker_swarmkit_api_deepcopy.Copy(&m.Annotations, &o.Annotations)
if o.Data != nil {
m.Data = make([]byte, len(o.Data))
copy(m.Data, o.Data)
}
}
func (m *NodeSpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1719,6 +1770,32 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintSpecs(dAtA, i, uint64(len(m.StopSignal)))
i += copy(dAtA[i:], m.StopSignal)
}
if len(m.Configs) > 0 {
for _, msg := range m.Configs {
dAtA[i] = 0xaa
i++
dAtA[i] = 0x1
i++
i = encodeVarintSpecs(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
if m.Privileges != nil {
dAtA[i] = 0xb2
i++
dAtA[i] = 0x1
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Privileges.Size()))
n23, err := m.Privileges.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n23
}
return i, nil
}
@ -1864,20 +1941,20 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
n23, err := m.Annotations.MarshalTo(dAtA[i:])
n24, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n23
i += n24
if m.DriverConfig != nil {
dAtA[i] = 0x12
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.DriverConfig.Size()))
n24, err := m.DriverConfig.MarshalTo(dAtA[i:])
n25, err := m.DriverConfig.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n24
i += n25
}
if m.Ipv6Enabled {
dAtA[i] = 0x18
@ -1903,11 +1980,11 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.IPAM.Size()))
n25, err := m.IPAM.MarshalTo(dAtA[i:])
n26, err := m.IPAM.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n25
i += n26
}
if m.Attachable {
dAtA[i] = 0x30
@ -1950,67 +2027,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
n26, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n26
dAtA[i] = 0x12
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
n27, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
n27, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n27
dAtA[i] = 0x1a
dAtA[i] = 0x12
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
n28, err := m.Orchestration.MarshalTo(dAtA[i:])
i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size()))
n28, err := m.AcceptancePolicy.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n28
dAtA[i] = 0x22
dAtA[i] = 0x1a
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
n29, err := m.Raft.MarshalTo(dAtA[i:])
i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size()))
n29, err := m.Orchestration.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n29
dAtA[i] = 0x2a
dAtA[i] = 0x22
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
n30, err := m.Dispatcher.MarshalTo(dAtA[i:])
i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size()))
n30, err := m.Raft.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n30
dAtA[i] = 0x32
dAtA[i] = 0x2a
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
n31, err := m.CAConfig.MarshalTo(dAtA[i:])
i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size()))
n31, err := m.Dispatcher.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n31
dAtA[i] = 0x3a
dAtA[i] = 0x32
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
n32, err := m.TaskDefaults.MarshalTo(dAtA[i:])
i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size()))
n32, err := m.CAConfig.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n32
dAtA[i] = 0x42
dAtA[i] = 0x3a
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
n33, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size()))
n33, err := m.TaskDefaults.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n33
dAtA[i] = 0x42
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size()))
n34, err := m.EncryptionConfig.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n34
return i, nil
}
@ -2032,11 +2109,43 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
n34, err := m.Annotations.MarshalTo(dAtA[i:])
n35, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n34
i += n35
if len(m.Data) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data)))
i += copy(dAtA[i:], m.Data)
}
return i, nil
}
func (m *ConfigSpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size()))
n36, err := m.Annotations.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n36
if len(m.Data) > 0 {
dAtA[i] = 0x12
i++
@ -2338,6 +2447,16 @@ func (m *ContainerSpec) Size() (n int) {
if l > 0 {
n += 2 + l + sovSpecs(uint64(l))
}
if len(m.Configs) > 0 {
for _, e := range m.Configs {
l = e.Size()
n += 2 + l + sovSpecs(uint64(l))
}
}
if m.Privileges != nil {
l = m.Privileges.Size()
n += 2 + l + sovSpecs(uint64(l))
}
return n
}
@ -2452,6 +2571,18 @@ func (m *SecretSpec) Size() (n int) {
return n
}
func (m *ConfigSpec) Size() (n int) {
var l int
_ = l
l = m.Annotations.Size()
n += 1 + l + sovSpecs(uint64(l))
l = len(m.Data)
if l > 0 {
n += 1 + l + sovSpecs(uint64(l))
}
return n
}
func sovSpecs(x uint64) (n int) {
for {
n++
@ -2635,6 +2766,8 @@ func (this *ContainerSpec) String() string {
`OpenStdin:` + fmt.Sprintf("%v", this.OpenStdin) + `,`,
`ReadOnly:` + fmt.Sprintf("%v", this.ReadOnly) + `,`,
`StopSignal:` + fmt.Sprintf("%v", this.StopSignal) + `,`,
`Configs:` + strings.Replace(fmt.Sprintf("%v", this.Configs), "ConfigReference", "ConfigReference", 1) + `,`,
`Privileges:` + strings.Replace(fmt.Sprintf("%v", this.Privileges), "Privileges", "Privileges", 1) + `,`,
`}`,
}, "")
return s
@ -2716,6 +2849,17 @@ func (this *SecretSpec) String() string {
}, "")
return s
}
func (this *ConfigSpec) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&ConfigSpec{`,
`Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`,
`Data:` + fmt.Sprintf("%v", this.Data) + `,`,
`}`,
}, "")
return s
}
func valueToStringSpecs(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@ -4492,6 +4636,70 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
}
m.StopSignal = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 21:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Configs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSpecs
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthSpecs
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Configs = append(m.Configs, &ConfigReference{})
if err := m.Configs[len(m.Configs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 22:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Privileges", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSpecs
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthSpecs
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Privileges == nil {
m.Privileges = &Privileges{}
}
if err := m.Privileges.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipSpecs(dAtA[iNdEx:])
@ -5456,6 +5664,117 @@ func (m *SecretSpec) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ConfigSpec) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSpecs
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ConfigSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ConfigSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSpecs
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthSpecs
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Annotations.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSpecs
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthSpecs
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipSpecs(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthSpecs
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipSpecs(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
@ -5564,117 +5883,119 @@ var (
func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
var fileDescriptorSpecs = []byte{
// 1779 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x41, 0x73, 0x1b, 0x49,
0x15, 0xb6, 0x6c, 0x59, 0x1a, 0xbd, 0x91, 0x13, 0xb9, 0xc9, 0x2e, 0x63, 0x85, 0x95, 0x15, 0x6d,
0x08, 0x5e, 0xb6, 0x90, 0x0b, 0x43, 0x2d, 0x59, 0xc2, 0x16, 0x48, 0x96, 0x70, 0x8c, 0xb1, 0xa3,
0x6a, 0x7b, 0x03, 0x39, 0xa9, 0xda, 0x33, 0x6d, 0x69, 0xca, 0xa3, 0xee, 0xa1, 0xa7, 0xc7, 0x5b,
0xba, 0x71, 0xdc, 0xca, 0x99, 0xab, 0x8b, 0x03, 0x7f, 0x26, 0x37, 0x28, 0x4e, 0x9c, 0x5c, 0xac,
0xfe, 0x02, 0x3f, 0x00, 0xaa, 0x7b, 0x7a, 0xa4, 0x51, 0x32, 0x4e, 0x52, 0x45, 0x6e, 0xfd, 0x5e,
0x7f, 0xdf, 0x9b, 0xd7, 0xaf, 0xbf, 0xee, 0xd7, 0x03, 0x76, 0x14, 0x52, 0x37, 0x6a, 0x87, 0x82,
0x4b, 0x8e, 0x90, 0xc7, 0xdd, 0x4b, 0x2a, 0xda, 0xd1, 0x37, 0x44, 0x4c, 0x2e, 0x7d, 0xd9, 0xbe,
0xfa, 0x69, 0xdd, 0x96, 0xd3, 0x90, 0x1a, 0x40, 0xfd, 0xde, 0x88, 0x8f, 0xb8, 0x1e, 0xee, 0xaa,
0x91, 0xf1, 0x36, 0x46, 0x9c, 0x8f, 0x02, 0xba, 0xab, 0xad, 0xf3, 0xf8, 0x62, 0xd7, 0x8b, 0x05,
0x91, 0x3e, 0x67, 0x66, 0x7e, 0xeb, 0xf5, 0x79, 0xc2, 0xa6, 0xc9, 0x54, 0xeb, 0xba, 0x08, 0xd6,
0x09, 0xf7, 0xe8, 0x69, 0x48, 0x5d, 0x74, 0x00, 0x36, 0x61, 0x8c, 0x4b, 0xcd, 0x8d, 0x9c, 0x42,
0xb3, 0xb0, 0x63, 0xef, 0x6d, 0xb7, 0xdf, 0x4c, 0xaa, 0xdd, 0x59, 0xc0, 0xba, 0xc5, 0x57, 0x37,
0xdb, 0x2b, 0x38, 0xcb, 0x44, 0xbf, 0x86, 0xaa, 0x47, 0x23, 0x5f, 0x50, 0x6f, 0x28, 0x78, 0x40,
0x9d, 0xd5, 0x66, 0x61, 0xe7, 0xce, 0xde, 0x0f, 0xf2, 0x22, 0xa9, 0x8f, 0x63, 0x1e, 0x50, 0x6c,
0x1b, 0x86, 0x32, 0xd0, 0x01, 0xc0, 0x84, 0x4e, 0xce, 0xa9, 0x88, 0xc6, 0x7e, 0xe8, 0xac, 0x69,
0xfa, 0x8f, 0x6e, 0xa3, 0xab, 0xdc, 0xdb, 0xc7, 0x73, 0x38, 0xce, 0x50, 0xd1, 0x31, 0x54, 0xc9,
0x15, 0xf1, 0x03, 0x72, 0xee, 0x07, 0xbe, 0x9c, 0x3a, 0x45, 0x1d, 0xea, 0xb3, 0xb7, 0x86, 0xea,
0x64, 0x08, 0x78, 0x89, 0xde, 0xf2, 0x00, 0x16, 0x1f, 0x42, 0x8f, 0xa0, 0x3c, 0xe8, 0x9f, 0xf4,
0x0e, 0x4f, 0x0e, 0x6a, 0x2b, 0xf5, 0xad, 0x97, 0xd7, 0xcd, 0x8f, 0x54, 0x8c, 0x05, 0x60, 0x40,
0x99, 0xe7, 0xb3, 0x11, 0xda, 0x01, 0xab, 0xb3, 0xbf, 0xdf, 0x1f, 0x9c, 0xf5, 0x7b, 0xb5, 0x42,
0xbd, 0xfe, 0xf2, 0xba, 0xf9, 0xf1, 0x32, 0xb0, 0xe3, 0xba, 0x34, 0x94, 0xd4, 0xab, 0x17, 0xbf,
0xfd, 0x5b, 0x63, 0xa5, 0xf5, 0x6d, 0x01, 0xaa, 0xd9, 0x24, 0xd0, 0x23, 0x28, 0x75, 0xf6, 0xcf,
0x0e, 0x9f, 0xf7, 0x6b, 0x2b, 0x0b, 0x7a, 0x16, 0xd1, 0x71, 0xa5, 0x7f, 0x45, 0xd1, 0x43, 0x58,
0x1f, 0x74, 0xbe, 0x3e, 0xed, 0xd7, 0x0a, 0x8b, 0x74, 0xb2, 0xb0, 0x01, 0x89, 0x23, 0x8d, 0xea,
0xe1, 0xce, 0xe1, 0x49, 0x6d, 0x35, 0x1f, 0xd5, 0x13, 0xc4, 0x67, 0x26, 0x95, 0xbf, 0x16, 0xc1,
0x3e, 0xa5, 0xe2, 0xca, 0x77, 0x3f, 0xb0, 0x44, 0xbe, 0x80, 0xa2, 0x24, 0xd1, 0xa5, 0x96, 0x86,
0x9d, 0x2f, 0x8d, 0x33, 0x12, 0x5d, 0xaa, 0x8f, 0x1a, 0xba, 0xc6, 0x2b, 0x65, 0x08, 0x1a, 0x06,
0xbe, 0x4b, 0x24, 0xf5, 0xb4, 0x32, 0xec, 0xbd, 0x1f, 0xe6, 0xb1, 0xf1, 0x1c, 0x65, 0xf2, 0x7f,
0xba, 0x82, 0x33, 0x54, 0xf4, 0x04, 0x4a, 0xa3, 0x80, 0x9f, 0x93, 0x40, 0x6b, 0xc2, 0xde, 0x7b,
0x90, 0x17, 0xe4, 0x40, 0x23, 0x16, 0x01, 0x0c, 0x05, 0x3d, 0x86, 0x52, 0x1c, 0x7a, 0x44, 0x52,
0xa7, 0xa4, 0xc9, 0xcd, 0x3c, 0xf2, 0xd7, 0x1a, 0xb1, 0xcf, 0xd9, 0x85, 0x3f, 0xc2, 0x06, 0x8f,
0x8e, 0xc0, 0x62, 0x54, 0x7e, 0xc3, 0xc5, 0x65, 0xe4, 0x94, 0x9b, 0x6b, 0x3b, 0xf6, 0xde, 0xe7,
0xb9, 0x62, 0x4c, 0x30, 0x1d, 0x29, 0x89, 0x3b, 0x9e, 0x50, 0x26, 0x93, 0x30, 0xdd, 0x55, 0xa7,
0x80, 0xe7, 0x01, 0xd0, 0xaf, 0xc0, 0xa2, 0xcc, 0x0b, 0xb9, 0xcf, 0xa4, 0x63, 0xdd, 0x9e, 0x48,
0xdf, 0x60, 0x54, 0x31, 0xf1, 0x9c, 0xa1, 0xd8, 0x82, 0x07, 0xc1, 0x39, 0x71, 0x2f, 0x9d, 0xca,
0x7b, 0x2e, 0x63, 0xce, 0xe8, 0x96, 0xa0, 0x38, 0xe1, 0x1e, 0x6d, 0xed, 0xc2, 0xe6, 0x1b, 0xa5,
0x46, 0x75, 0xb0, 0x4c, 0xa9, 0x13, 0x8d, 0x14, 0xf1, 0xdc, 0x6e, 0xdd, 0x85, 0x8d, 0xa5, 0xb2,
0xb6, 0xfe, 0x59, 0x04, 0x2b, 0xdd, 0x6b, 0xd4, 0x81, 0x8a, 0xcb, 0x99, 0x24, 0x3e, 0xa3, 0xc2,
0xc8, 0x2b, 0x77, 0x67, 0xf6, 0x53, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, 0x2d, 0x54,
0x04, 0x8d, 0x78, 0x2c, 0x5c, 0x1a, 0x19, 0x7d, 0xed, 0xe4, 0x2b, 0x24, 0x01, 0x61, 0xfa, 0xa7,
0xd8, 0x17, 0x54, 0x55, 0x39, 0xc2, 0x0b, 0x2a, 0x7a, 0x02, 0x65, 0x41, 0x23, 0x49, 0x84, 0x7c,
0x9b, 0x44, 0x70, 0x02, 0x19, 0xf0, 0xc0, 0x77, 0xa7, 0x38, 0x65, 0xa0, 0x27, 0x50, 0x09, 0x03,
0xe2, 0xea, 0xa8, 0xce, 0xba, 0xa6, 0x7f, 0x92, 0x47, 0x1f, 0xa4, 0x20, 0xbc, 0xc0, 0xa3, 0x2f,
0x01, 0x02, 0x3e, 0x1a, 0x7a, 0xc2, 0xbf, 0xa2, 0xc2, 0x48, 0xac, 0x9e, 0xc7, 0xee, 0x69, 0x04,
0xae, 0x04, 0x7c, 0x94, 0x0c, 0xd1, 0xc1, 0xff, 0xa5, 0xaf, 0x8c, 0xb6, 0x8e, 0x00, 0xc8, 0x7c,
0xd6, 0xa8, 0xeb, 0xb3, 0xf7, 0x0a, 0x65, 0x76, 0x24, 0x43, 0x47, 0x0f, 0xa0, 0x7a, 0xc1, 0x85,
0x4b, 0x87, 0xe6, 0xd4, 0x54, 0xb4, 0x26, 0x6c, 0xed, 0x4b, 0xf4, 0x85, 0xba, 0x50, 0x1e, 0x51,
0x46, 0x85, 0xef, 0x3a, 0xa0, 0x3f, 0xf6, 0x28, 0xf7, 0x40, 0x26, 0x10, 0x1c, 0x33, 0xe9, 0x4f,
0xa8, 0xf9, 0x52, 0x4a, 0xec, 0x56, 0xa0, 0x2c, 0x92, 0x99, 0xd6, 0x1f, 0x01, 0xbd, 0x89, 0x45,
0x08, 0x8a, 0x97, 0x3e, 0xf3, 0xb4, 0xb0, 0x2a, 0x58, 0x8f, 0x51, 0x1b, 0xca, 0x21, 0x99, 0x06,
0x9c, 0x78, 0x46, 0x2c, 0xf7, 0xda, 0x49, 0xbf, 0x6c, 0xa7, 0xfd, 0xb2, 0xdd, 0x61, 0x53, 0x9c,
0x82, 0x5a, 0x47, 0xf0, 0x51, 0xee, 0x92, 0xd1, 0x1e, 0x54, 0xe7, 0x22, 0x1c, 0xfa, 0xe6, 0x23,
0xdd, 0xbb, 0xb3, 0x9b, 0x6d, 0x7b, 0xae, 0xd6, 0xc3, 0x1e, 0xb6, 0xe7, 0xa0, 0x43, 0xaf, 0xf5,
0x17, 0x0b, 0x36, 0x96, 0xa4, 0x8c, 0xee, 0xc1, 0xba, 0x3f, 0x21, 0x23, 0x6a, 0x72, 0x4c, 0x0c,
0xd4, 0x87, 0x52, 0x40, 0xce, 0x69, 0xa0, 0x04, 0xad, 0x36, 0xf5, 0x27, 0xef, 0x3c, 0x13, 0xed,
0xdf, 0x6b, 0x7c, 0x9f, 0x49, 0x31, 0xc5, 0x86, 0x8c, 0x1c, 0x28, 0xbb, 0x7c, 0x32, 0x21, 0x4c,
0x5d, 0x9d, 0x6b, 0x3b, 0x15, 0x9c, 0x9a, 0xaa, 0x32, 0x44, 0x8c, 0x22, 0xa7, 0xa8, 0xdd, 0x7a,
0x8c, 0x6a, 0xb0, 0x46, 0xd9, 0x95, 0xb3, 0xae, 0x5d, 0x6a, 0xa8, 0x3c, 0x9e, 0x9f, 0x28, 0xb2,
0x82, 0xd5, 0x50, 0xf1, 0xe2, 0x88, 0x0a, 0xa7, 0x9c, 0x54, 0x54, 0x8d, 0xd1, 0x2f, 0xa0, 0x34,
0xe1, 0x31, 0x93, 0x91, 0x63, 0xe9, 0x64, 0xb7, 0xf2, 0x92, 0x3d, 0x56, 0x08, 0x73, 0xb5, 0x1b,
0x38, 0xea, 0xc3, 0x66, 0x24, 0x79, 0x38, 0x1c, 0x09, 0xe2, 0xd2, 0x61, 0x48, 0x85, 0xcf, 0x3d,
0x73, 0x35, 0x6d, 0xbd, 0xb1, 0x29, 0x3d, 0xf3, 0xc8, 0xc1, 0x77, 0x15, 0xe7, 0x40, 0x51, 0x06,
0x9a, 0x81, 0x06, 0x50, 0x0d, 0xe3, 0x20, 0x18, 0xf2, 0x30, 0xe9, 0x52, 0x89, 0x9e, 0xde, 0xa3,
0x64, 0x83, 0x38, 0x08, 0x9e, 0x25, 0x24, 0x6c, 0x87, 0x0b, 0x03, 0x7d, 0x0c, 0xa5, 0x91, 0xe0,
0x71, 0x18, 0x39, 0xb6, 0x2e, 0x86, 0xb1, 0xd0, 0x57, 0x50, 0x8e, 0xa8, 0x2b, 0xa8, 0x8c, 0x9c,
0xaa, 0x5e, 0xea, 0xa7, 0x79, 0x1f, 0x39, 0xd5, 0x10, 0x4c, 0x2f, 0xa8, 0xa0, 0xcc, 0xa5, 0x38,
0xe5, 0xa0, 0x2d, 0x58, 0x93, 0x72, 0xea, 0x6c, 0x34, 0x0b, 0x3b, 0x56, 0xb7, 0x3c, 0xbb, 0xd9,
0x5e, 0x3b, 0x3b, 0x7b, 0x81, 0x95, 0x4f, 0xdd, 0xa0, 0x63, 0x1e, 0x49, 0x46, 0x26, 0xd4, 0xb9,
0xa3, 0x6b, 0x3b, 0xb7, 0xd1, 0x0b, 0x00, 0x8f, 0x45, 0x43, 0x57, 0x1f, 0x59, 0xe7, 0xae, 0x5e,
0xdd, 0xe7, 0xef, 0x5e, 0x5d, 0xef, 0xe4, 0xd4, 0x74, 0x91, 0x8d, 0xd9, 0xcd, 0x76, 0x65, 0x6e,
0xe2, 0x8a, 0xc7, 0xa2, 0x64, 0x88, 0xba, 0x60, 0x8f, 0x29, 0x09, 0xe4, 0xd8, 0x1d, 0x53, 0xf7,
0xd2, 0xa9, 0xdd, 0xde, 0x16, 0x9e, 0x6a, 0x98, 0x89, 0x90, 0x25, 0x29, 0x05, 0xab, 0x54, 0x23,
0x67, 0x53, 0xd7, 0x2a, 0x31, 0xd0, 0x27, 0x00, 0x3c, 0xa4, 0x6c, 0x18, 0x49, 0xcf, 0x67, 0x0e,
0x52, 0x4b, 0xc6, 0x15, 0xe5, 0x39, 0x55, 0x0e, 0x74, 0x5f, 0x5d, 0xda, 0xc4, 0x1b, 0x72, 0x16,
0x4c, 0x9d, 0xef, 0xe9, 0x59, 0x4b, 0x39, 0x9e, 0xb1, 0x60, 0x8a, 0xb6, 0xc1, 0xd6, 0xba, 0x88,
0xfc, 0x11, 0x23, 0x81, 0x73, 0x4f, 0xd7, 0x03, 0x94, 0xeb, 0x54, 0x7b, 0xea, 0x5f, 0x82, 0x9d,
0x91, 0xbb, 0x92, 0xe9, 0x25, 0x9d, 0x9a, 0x13, 0xa4, 0x86, 0x2a, 0xa7, 0x2b, 0x12, 0xc4, 0xc9,
0x53, 0xb4, 0x82, 0x13, 0xe3, 0x97, 0xab, 0x8f, 0x0b, 0xf5, 0x3d, 0xb0, 0x33, 0xdb, 0x8e, 0x3e,
0x85, 0x0d, 0x41, 0x47, 0x7e, 0x24, 0xc5, 0x74, 0x48, 0x62, 0x39, 0x76, 0x7e, 0xa3, 0x09, 0xd5,
0xd4, 0xd9, 0x89, 0xe5, 0xb8, 0x3e, 0x84, 0x45, 0xf5, 0x50, 0x13, 0x6c, 0xb5, 0x2b, 0x11, 0x15,
0x57, 0x54, 0xa8, 0x76, 0xa7, 0x16, 0x9d, 0x75, 0x29, 0xf5, 0x44, 0x94, 0x08, 0x77, 0xac, 0x0f,
0x6f, 0x05, 0x1b, 0x4b, 0x9d, 0xc6, 0x54, 0xa2, 0xe6, 0x34, 0x1a, 0xb3, 0xf5, 0x9f, 0x02, 0x54,
0xb3, 0x5d, 0x1b, 0xed, 0x27, 0xdd, 0x56, 0x2f, 0xe9, 0xce, 0xde, 0xee, 0xbb, 0xba, 0xbc, 0xee,
0x6d, 0x41, 0xac, 0x82, 0x1d, 0xab, 0x07, 0xb6, 0x26, 0xa3, 0x9f, 0xc3, 0x7a, 0xc8, 0x85, 0x4c,
0xef, 0x90, 0x46, 0x6e, 0x3f, 0xe2, 0x22, 0xed, 0x05, 0x09, 0xb8, 0x35, 0x86, 0x3b, 0xcb, 0xd1,
0xd0, 0x43, 0x58, 0x7b, 0x7e, 0x38, 0xa8, 0xad, 0xd4, 0xef, 0xbf, 0xbc, 0x6e, 0x7e, 0x7f, 0x79,
0xf2, 0xb9, 0x2f, 0x64, 0x4c, 0x82, 0xc3, 0x01, 0xfa, 0x31, 0xac, 0xf7, 0x4e, 0x4e, 0x31, 0xae,
0x15, 0xea, 0xdb, 0x2f, 0xaf, 0x9b, 0xf7, 0x97, 0x71, 0x6a, 0x8a, 0xc7, 0xcc, 0xc3, 0xfc, 0x7c,
0xfe, 0xd8, 0xfc, 0xfb, 0x2a, 0xd8, 0xe6, 0x6a, 0xfd, 0xd0, 0xff, 0x23, 0x1b, 0x49, 0x2f, 0x4d,
0xcf, 0xcc, 0xea, 0x3b, 0x5b, 0x6a, 0x35, 0x21, 0x98, 0x3d, 0x7e, 0x00, 0x55, 0x3f, 0xbc, 0xfa,
0x62, 0x48, 0x19, 0x39, 0x0f, 0xcc, 0xbb, 0xd3, 0xc2, 0xb6, 0xf2, 0xf5, 0x13, 0x97, 0x3a, 0xb0,
0x3e, 0x93, 0x54, 0x30, 0xf3, 0xa2, 0xb4, 0xf0, 0xdc, 0x46, 0x5f, 0x41, 0xd1, 0x0f, 0xc9, 0xc4,
0xbc, 0x03, 0x72, 0x57, 0x70, 0x38, 0xe8, 0x1c, 0x1b, 0x0d, 0x76, 0xad, 0xd9, 0xcd, 0x76, 0x51,
0x39, 0xb0, 0xa6, 0xa1, 0x46, 0xda, 0x8a, 0xd5, 0x97, 0xf4, 0xe5, 0x6b, 0xe1, 0x8c, 0x47, 0xe9,
0xc8, 0x67, 0x23, 0x41, 0xa3, 0x48, 0x5f, 0xc3, 0x16, 0x4e, 0xcd, 0xd6, 0x7f, 0x8b, 0x60, 0xef,
0x07, 0x71, 0x24, 0x4d, 0x73, 0xf9, 0x60, 0x15, 0x7d, 0x01, 0x9b, 0x44, 0xff, 0xb4, 0x10, 0xa6,
0x6e, 0x6a, 0xfd, 0xf8, 0x31, 0x55, 0x7d, 0x98, 0x1b, 0x6e, 0x0e, 0x4e, 0x1e, 0x4a, 0xdd, 0x92,
0x8a, 0xe9, 0x14, 0x70, 0x8d, 0xbc, 0x36, 0x83, 0x4e, 0x61, 0x83, 0x0b, 0x77, 0x4c, 0x23, 0x99,
0xdc, 0xef, 0xe6, 0x91, 0x9f, 0xfb, 0xfb, 0xf7, 0x2c, 0x0b, 0x34, 0x97, 0x5b, 0x92, 0xed, 0x72,
0x0c, 0xf4, 0x18, 0x8a, 0x82, 0x5c, 0xa4, 0x0f, 0xb9, 0x5c, 0xe5, 0x63, 0x72, 0x21, 0x97, 0x42,
0x68, 0x06, 0xfa, 0x1d, 0x80, 0xe7, 0x47, 0x21, 0x91, 0xee, 0x98, 0x0a, 0xb3, 0x83, 0xb9, 0x4b,
0xec, 0xcd, 0x51, 0x4b, 0x51, 0x32, 0x6c, 0x74, 0x04, 0x15, 0x97, 0xa4, 0x1a, 0x2c, 0xdd, 0xfe,
0xe7, 0xb3, 0xdf, 0x31, 0x21, 0x6a, 0x2a, 0xc4, 0xec, 0x66, 0xdb, 0x4a, 0x3d, 0xd8, 0x72, 0x89,
0xd1, 0xe4, 0x11, 0x6c, 0xa8, 0x3f, 0xa2, 0xa1, 0x47, 0x2f, 0x48, 0x1c, 0xc8, 0x64, 0xef, 0x6f,
0xb9, 0xac, 0xd5, 0xf3, 0xba, 0x67, 0x70, 0x26, 0xaf, 0xaa, 0xcc, 0xf8, 0xd0, 0x1f, 0x60, 0x93,
0x32, 0x57, 0x4c, 0xb5, 0x02, 0xd3, 0x0c, 0xad, 0xdb, 0x17, 0xdb, 0x9f, 0x83, 0x97, 0x16, 0x5b,
0xa3, 0xaf, 0xf9, 0x5b, 0x3e, 0x40, 0xd2, 0xfe, 0x3e, 0xac, 0xfe, 0x10, 0x14, 0x3d, 0x22, 0x89,
0x96, 0x5c, 0x15, 0xeb, 0x71, 0xd7, 0x79, 0xf5, 0x5d, 0x63, 0xe5, 0x5f, 0xdf, 0x35, 0x56, 0xfe,
0x3c, 0x6b, 0x14, 0x5e, 0xcd, 0x1a, 0x85, 0x7f, 0xcc, 0x1a, 0x85, 0x7f, 0xcf, 0x1a, 0x85, 0xf3,
0x92, 0x7e, 0x34, 0xfc, 0xec, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x3e, 0xe8, 0xcb, 0x6d,
0x11, 0x00, 0x00,
// 1824 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0x4f, 0x73, 0x1b, 0x49,
0x15, 0xb7, 0x6c, 0x59, 0x7f, 0xde, 0xc8, 0x89, 0xd2, 0x24, 0x61, 0xac, 0xb0, 0xb2, 0xa2, 0x0d,
0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0x4b, 0x58, 0x40, 0xb2, 0x84, 0x63, 0x8c, 0x1d, 0x55,
0xdb, 0x1b, 0xc8, 0x49, 0xd5, 0x9e, 0x69, 0x4b, 0x53, 0x1e, 0x75, 0x0f, 0xdd, 0x3d, 0xda, 0xd2,
0x8d, 0xe3, 0x56, 0xae, 0x9c, 0x5d, 0x1c, 0xf8, 0x32, 0xb9, 0x41, 0x71, 0xe2, 0xe4, 0x62, 0xfd,
0x15, 0xf8, 0x00, 0x50, 0xdd, 0xd3, 0xa3, 0x3f, 0xc9, 0x78, 0x93, 0x2a, 0xc2, 0xad, 0xfb, 0xcd,
0xef, 0xf7, 0xfa, 0xf5, 0xeb, 0x5f, 0xf7, 0x7b, 0x03, 0x8e, 0x8c, 0xa8, 0x27, 0x5b, 0x91, 0xe0,
0x8a, 0x23, 0xe4, 0x73, 0xef, 0x82, 0x8a, 0x96, 0xfc, 0x8a, 0x88, 0xf1, 0x45, 0xa0, 0x5a, 0x93,
0x1f, 0xd7, 0x1c, 0x35, 0x8d, 0xa8, 0x05, 0xd4, 0xee, 0x0e, 0xf9, 0x90, 0x9b, 0xe1, 0x8e, 0x1e,
0x59, 0x6b, 0x7d, 0xc8, 0xf9, 0x30, 0xa4, 0x3b, 0x66, 0x76, 0x16, 0x9f, 0xef, 0xf8, 0xb1, 0x20,
0x2a, 0xe0, 0xcc, 0x7e, 0xdf, 0x7c, 0xf3, 0x3b, 0x61, 0xd3, 0xe4, 0x53, 0xf3, 0x32, 0x0f, 0xa5,
0x63, 0xee, 0xd3, 0x93, 0x88, 0x7a, 0x68, 0x1f, 0x1c, 0xc2, 0x18, 0x57, 0x86, 0x2b, 0xdd, 0x5c,
0x23, 0xb7, 0xed, 0xec, 0x6e, 0xb5, 0xde, 0x0e, 0xaa, 0xd5, 0x9e, 0xc3, 0x3a, 0xf9, 0xd7, 0x57,
0x5b, 0x2b, 0x78, 0x91, 0x89, 0x7e, 0x05, 0x15, 0x9f, 0xca, 0x40, 0x50, 0x7f, 0x20, 0x78, 0x48,
0xdd, 0xd5, 0x46, 0x6e, 0xfb, 0xd6, 0xee, 0xf7, 0xb2, 0x3c, 0xe9, 0xc5, 0x31, 0x0f, 0x29, 0x76,
0x2c, 0x43, 0x4f, 0xd0, 0x3e, 0xc0, 0x98, 0x8e, 0xcf, 0xa8, 0x90, 0xa3, 0x20, 0x72, 0xd7, 0x0c,
0xfd, 0x07, 0x37, 0xd1, 0x75, 0xec, 0xad, 0xa3, 0x19, 0x1c, 0x2f, 0x50, 0xd1, 0x11, 0x54, 0xc8,
0x84, 0x04, 0x21, 0x39, 0x0b, 0xc2, 0x40, 0x4d, 0xdd, 0xbc, 0x71, 0xf5, 0xc9, 0xb7, 0xba, 0x6a,
0x2f, 0x10, 0xf0, 0x12, 0xbd, 0xe9, 0x03, 0xcc, 0x17, 0x42, 0x8f, 0xa1, 0xd8, 0xef, 0x1d, 0x77,
0x0f, 0x8e, 0xf7, 0xab, 0x2b, 0xb5, 0xcd, 0x57, 0x97, 0x8d, 0x7b, 0xda, 0xc7, 0x1c, 0xd0, 0xa7,
0xcc, 0x0f, 0xd8, 0x10, 0x6d, 0x43, 0xa9, 0xbd, 0xb7, 0xd7, 0xeb, 0x9f, 0xf6, 0xba, 0xd5, 0x5c,
0xad, 0xf6, 0xea, 0xb2, 0x71, 0x7f, 0x19, 0xd8, 0xf6, 0x3c, 0x1a, 0x29, 0xea, 0xd7, 0xf2, 0x5f,
0xff, 0xb5, 0xbe, 0xd2, 0xfc, 0x3a, 0x07, 0x95, 0xc5, 0x20, 0xd0, 0x63, 0x28, 0xb4, 0xf7, 0x4e,
0x0f, 0x5e, 0xf4, 0xaa, 0x2b, 0x73, 0xfa, 0x22, 0xa2, 0xed, 0xa9, 0x60, 0x42, 0xd1, 0x23, 0x58,
0xef, 0xb7, 0xbf, 0x3c, 0xe9, 0x55, 0x73, 0xf3, 0x70, 0x16, 0x61, 0x7d, 0x12, 0x4b, 0x83, 0xea,
0xe2, 0xf6, 0xc1, 0x71, 0x75, 0x35, 0x1b, 0xd5, 0x15, 0x24, 0x60, 0x36, 0x94, 0xbf, 0xe4, 0xc1,
0x39, 0xa1, 0x62, 0x12, 0x78, 0x1f, 0x58, 0x22, 0x9f, 0x41, 0x5e, 0x11, 0x79, 0x61, 0xa4, 0xe1,
0x64, 0x4b, 0xe3, 0x94, 0xc8, 0x0b, 0xbd, 0xa8, 0xa5, 0x1b, 0xbc, 0x56, 0x86, 0xa0, 0x51, 0x18,
0x78, 0x44, 0x51, 0xdf, 0x28, 0xc3, 0xd9, 0xfd, 0x7e, 0x16, 0x1b, 0xcf, 0x50, 0x36, 0xfe, 0x67,
0x2b, 0x78, 0x81, 0x8a, 0x9e, 0x42, 0x61, 0x18, 0xf2, 0x33, 0x12, 0x1a, 0x4d, 0x38, 0xbb, 0x0f,
0xb3, 0x9c, 0xec, 0x1b, 0xc4, 0xdc, 0x81, 0xa5, 0xa0, 0x27, 0x50, 0x88, 0x23, 0x9f, 0x28, 0xea,
0x16, 0x0c, 0xb9, 0x91, 0x45, 0xfe, 0xd2, 0x20, 0xf6, 0x38, 0x3b, 0x0f, 0x86, 0xd8, 0xe2, 0xd1,
0x21, 0x94, 0x18, 0x55, 0x5f, 0x71, 0x71, 0x21, 0xdd, 0x62, 0x63, 0x6d, 0xdb, 0xd9, 0xfd, 0x34,
0x53, 0x8c, 0x09, 0xa6, 0xad, 0x14, 0xf1, 0x46, 0x63, 0xca, 0x54, 0xe2, 0xa6, 0xb3, 0xea, 0xe6,
0xf0, 0xcc, 0x01, 0xfa, 0x05, 0x94, 0x28, 0xf3, 0x23, 0x1e, 0x30, 0xe5, 0x96, 0x6e, 0x0e, 0xa4,
0x67, 0x31, 0x3a, 0x99, 0x78, 0xc6, 0xd0, 0x6c, 0xc1, 0xc3, 0xf0, 0x8c, 0x78, 0x17, 0x6e, 0xf9,
0x3d, 0xb7, 0x31, 0x63, 0x74, 0x0a, 0x90, 0x1f, 0x73, 0x9f, 0x36, 0x77, 0xe0, 0xce, 0x5b, 0xa9,
0x46, 0x35, 0x28, 0xd9, 0x54, 0x27, 0x1a, 0xc9, 0xe3, 0xd9, 0xbc, 0x79, 0x1b, 0x36, 0x96, 0xd2,
0xda, 0xfc, 0x47, 0x1e, 0x4a, 0xe9, 0x59, 0xa3, 0x36, 0x94, 0x3d, 0xce, 0x14, 0x09, 0x18, 0x15,
0x56, 0x5e, 0x99, 0x27, 0xb3, 0x97, 0x82, 0x34, 0xeb, 0xd9, 0x0a, 0x9e, 0xb3, 0xd0, 0x6f, 0xa0,
0x2c, 0xa8, 0xe4, 0xb1, 0xf0, 0xa8, 0xb4, 0xfa, 0xda, 0xce, 0x56, 0x48, 0x02, 0xc2, 0xf4, 0x8f,
0x71, 0x20, 0xa8, 0xce, 0xb2, 0xc4, 0x73, 0x2a, 0x7a, 0x0a, 0x45, 0x41, 0xa5, 0x22, 0x42, 0x7d,
0x9b, 0x44, 0x70, 0x02, 0xe9, 0xf3, 0x30, 0xf0, 0xa6, 0x38, 0x65, 0xa0, 0xa7, 0x50, 0x8e, 0x42,
0xe2, 0x19, 0xaf, 0xee, 0xba, 0xa1, 0x7f, 0x94, 0x45, 0xef, 0xa7, 0x20, 0x3c, 0xc7, 0xa3, 0xcf,
0x01, 0x42, 0x3e, 0x1c, 0xf8, 0x22, 0x98, 0x50, 0x61, 0x25, 0x56, 0xcb, 0x62, 0x77, 0x0d, 0x02,
0x97, 0x43, 0x3e, 0x4c, 0x86, 0x68, 0xff, 0x7f, 0xd2, 0xd7, 0x82, 0xb6, 0x0e, 0x01, 0xc8, 0xec,
0xab, 0x55, 0xd7, 0x27, 0xef, 0xe5, 0xca, 0x9e, 0xc8, 0x02, 0x1d, 0x3d, 0x84, 0xca, 0x39, 0x17,
0x1e, 0x1d, 0xd8, 0x5b, 0x53, 0x36, 0x9a, 0x70, 0x8c, 0x2d, 0xd1, 0x17, 0xea, 0x40, 0x71, 0x48,
0x19, 0x15, 0x81, 0xe7, 0x82, 0x59, 0xec, 0x71, 0xe6, 0x85, 0x4c, 0x20, 0x38, 0x66, 0x2a, 0x18,
0x53, 0xbb, 0x52, 0x4a, 0xec, 0x94, 0xa1, 0x28, 0x92, 0x2f, 0xcd, 0x3f, 0x00, 0x7a, 0x1b, 0x8b,
0x10, 0xe4, 0x2f, 0x02, 0xe6, 0x1b, 0x61, 0x95, 0xb1, 0x19, 0xa3, 0x16, 0x14, 0x23, 0x32, 0x0d,
0x39, 0xf1, 0xad, 0x58, 0xee, 0xb6, 0x92, 0x7a, 0xd9, 0x4a, 0xeb, 0x65, 0xab, 0xcd, 0xa6, 0x38,
0x05, 0x35, 0x0f, 0xe1, 0x5e, 0xe6, 0x96, 0xd1, 0x2e, 0x54, 0x66, 0x22, 0x1c, 0x04, 0x76, 0x91,
0xce, 0xed, 0xeb, 0xab, 0x2d, 0x67, 0xa6, 0xd6, 0x83, 0x2e, 0x76, 0x66, 0xa0, 0x03, 0xbf, 0xf9,
0xe7, 0x32, 0x6c, 0x2c, 0x49, 0x19, 0xdd, 0x85, 0xf5, 0x60, 0x4c, 0x86, 0xd4, 0xc6, 0x98, 0x4c,
0x50, 0x0f, 0x0a, 0x21, 0x39, 0xa3, 0xa1, 0x16, 0xb4, 0x3e, 0xd4, 0x1f, 0xbd, 0xf3, 0x4e, 0xb4,
0x7e, 0x67, 0xf0, 0x3d, 0xa6, 0xc4, 0x14, 0x5b, 0x32, 0x72, 0xa1, 0xe8, 0xf1, 0xf1, 0x98, 0x30,
0xfd, 0x74, 0xae, 0x6d, 0x97, 0x71, 0x3a, 0xd5, 0x99, 0x21, 0x62, 0x28, 0xdd, 0xbc, 0x31, 0x9b,
0x31, 0xaa, 0xc2, 0x1a, 0x65, 0x13, 0x77, 0xdd, 0x98, 0xf4, 0x50, 0x5b, 0xfc, 0x20, 0x51, 0x64,
0x19, 0xeb, 0xa1, 0xe6, 0xc5, 0x92, 0x0a, 0xb7, 0x98, 0x64, 0x54, 0x8f, 0xd1, 0xcf, 0xa0, 0x30,
0xe6, 0x31, 0x53, 0xd2, 0x2d, 0x99, 0x60, 0x37, 0xb3, 0x82, 0x3d, 0xd2, 0x08, 0xfb, 0xb4, 0x5b,
0x38, 0xea, 0xc1, 0x1d, 0xa9, 0x78, 0x34, 0x18, 0x0a, 0xe2, 0xd1, 0x41, 0x44, 0x45, 0xc0, 0x7d,
0xfb, 0x34, 0x6d, 0xbe, 0x75, 0x28, 0x5d, 0xdb, 0xe4, 0xe0, 0xdb, 0x9a, 0xb3, 0xaf, 0x29, 0x7d,
0xc3, 0x40, 0x7d, 0xa8, 0x44, 0x71, 0x18, 0x0e, 0x78, 0x94, 0x54, 0xa9, 0x44, 0x4f, 0xef, 0x91,
0xb2, 0x7e, 0x1c, 0x86, 0xcf, 0x13, 0x12, 0x76, 0xa2, 0xf9, 0x04, 0xdd, 0x87, 0xc2, 0x50, 0xf0,
0x38, 0x92, 0xae, 0x63, 0x92, 0x61, 0x67, 0xe8, 0x0b, 0x28, 0x4a, 0xea, 0x09, 0xaa, 0xa4, 0x5b,
0x31, 0x5b, 0xfd, 0x38, 0x6b, 0x91, 0x13, 0x03, 0xc1, 0xf4, 0x9c, 0x0a, 0xca, 0x3c, 0x8a, 0x53,
0x0e, 0xda, 0x84, 0x35, 0xa5, 0xa6, 0xee, 0x46, 0x23, 0xb7, 0x5d, 0xea, 0x14, 0xaf, 0xaf, 0xb6,
0xd6, 0x4e, 0x4f, 0x5f, 0x62, 0x6d, 0xd3, 0x2f, 0xe8, 0x88, 0x4b, 0xc5, 0xc8, 0x98, 0xba, 0xb7,
0x4c, 0x6e, 0x67, 0x73, 0xf4, 0x12, 0xc0, 0x67, 0x72, 0xe0, 0x99, 0x2b, 0xeb, 0xde, 0x36, 0xbb,
0xfb, 0xf4, 0xdd, 0xbb, 0xeb, 0x1e, 0x9f, 0xd8, 0x2a, 0xb2, 0x71, 0x7d, 0xb5, 0x55, 0x9e, 0x4d,
0x71, 0xd9, 0x67, 0x32, 0x19, 0xa2, 0x0e, 0x38, 0x23, 0x4a, 0x42, 0x35, 0xf2, 0x46, 0xd4, 0xbb,
0x70, 0xab, 0x37, 0x97, 0x85, 0x67, 0x06, 0x66, 0x3d, 0x2c, 0x92, 0xb4, 0x82, 0x75, 0xa8, 0xd2,
0xbd, 0x63, 0x72, 0x95, 0x4c, 0xd0, 0x47, 0x00, 0x3c, 0xa2, 0x6c, 0x20, 0x95, 0x1f, 0x30, 0x17,
0xe9, 0x2d, 0xe3, 0xb2, 0xb6, 0x9c, 0x68, 0x03, 0x7a, 0xa0, 0x1f, 0x6d, 0xe2, 0x0f, 0x38, 0x0b,
0xa7, 0xee, 0x77, 0xcc, 0xd7, 0x92, 0x36, 0x3c, 0x67, 0xe1, 0x14, 0x6d, 0x81, 0x63, 0x74, 0x21,
0x83, 0x21, 0x23, 0xa1, 0x7b, 0xd7, 0xe4, 0x03, 0xb4, 0xe9, 0xc4, 0x58, 0xf4, 0x39, 0x24, 0xd9,
0x90, 0xee, 0xbd, 0x9b, 0xcf, 0xc1, 0x06, 0x3b, 0x3f, 0x07, 0xcb, 0x41, 0xbf, 0x04, 0x88, 0x44,
0x30, 0x09, 0x42, 0x3a, 0xa4, 0xd2, 0xbd, 0x6f, 0x36, 0x5d, 0xcf, 0x7c, 0xad, 0x67, 0x28, 0xbc,
0xc0, 0xa8, 0x7d, 0x0e, 0xce, 0xc2, 0x6d, 0xd3, 0xb7, 0xe4, 0x82, 0x4e, 0xed, 0x05, 0xd6, 0x43,
0x9d, 0x92, 0x09, 0x09, 0xe3, 0xa4, 0x13, 0x2e, 0xe3, 0x64, 0xf2, 0xf3, 0xd5, 0x27, 0xb9, 0xda,
0x2e, 0x38, 0x0b, 0xaa, 0x43, 0x1f, 0xc3, 0x86, 0xa0, 0xc3, 0x40, 0x2a, 0x31, 0x1d, 0x90, 0x58,
0x8d, 0xdc, 0x5f, 0x1b, 0x42, 0x25, 0x35, 0xb6, 0x63, 0x35, 0xaa, 0x0d, 0x60, 0x7e, 0x78, 0xa8,
0x01, 0x8e, 0x16, 0x85, 0xa4, 0x62, 0x42, 0x85, 0xae, 0xb6, 0x3a, 0xe7, 0x8b, 0x26, 0x2d, 0x5e,
0x49, 0x89, 0xf0, 0x46, 0xe6, 0xed, 0x28, 0x63, 0x3b, 0xd3, 0x8f, 0x41, 0x7a, 0x43, 0xec, 0x63,
0x60, 0xa7, 0xcd, 0x7f, 0xe7, 0xa0, 0xb2, 0xd8, 0x34, 0xa0, 0xbd, 0xa4, 0xd8, 0x9b, 0x2d, 0xdd,
0xda, 0xdd, 0x79, 0x57, 0x93, 0x61, 0x4a, 0x6b, 0x18, 0x6b, 0x67, 0x47, 0xba, 0xbf, 0x37, 0x64,
0xf4, 0x53, 0x58, 0x8f, 0xb8, 0x50, 0xe9, 0x13, 0x96, 0x9d, 0x60, 0x2e, 0xd2, 0x52, 0x94, 0x80,
0x9b, 0x23, 0xb8, 0xb5, 0xec, 0x0d, 0x3d, 0x82, 0xb5, 0x17, 0x07, 0xfd, 0xea, 0x4a, 0xed, 0xc1,
0xab, 0xcb, 0xc6, 0x77, 0x97, 0x3f, 0xbe, 0x08, 0x84, 0x8a, 0x49, 0x78, 0xd0, 0x47, 0x3f, 0x84,
0xf5, 0xee, 0xf1, 0x09, 0xc6, 0xd5, 0x5c, 0x6d, 0xeb, 0xd5, 0x65, 0xe3, 0xc1, 0x32, 0x4e, 0x7f,
0xe2, 0x31, 0xf3, 0x31, 0x3f, 0x9b, 0xf5, 0xba, 0x7f, 0x5b, 0x05, 0xc7, 0xbe, 0xec, 0x1f, 0xfa,
0x77, 0x68, 0x23, 0x29, 0xe5, 0xe9, 0x95, 0x5d, 0x7d, 0x67, 0x45, 0xaf, 0x24, 0x04, 0x7b, 0xc6,
0x0f, 0xa1, 0x12, 0x44, 0x93, 0xcf, 0x06, 0x94, 0x91, 0xb3, 0xd0, 0xb6, 0xbd, 0x25, 0xec, 0x68,
0x5b, 0x2f, 0x31, 0xe9, 0xf7, 0x22, 0x60, 0x8a, 0x0a, 0x66, 0x1b, 0xda, 0x12, 0x9e, 0xcd, 0xd1,
0x17, 0x90, 0x0f, 0x22, 0x32, 0xb6, 0x6d, 0x48, 0xe6, 0x0e, 0x0e, 0xfa, 0xed, 0x23, 0xab, 0xc1,
0x4e, 0xe9, 0xfa, 0x6a, 0x2b, 0xaf, 0x0d, 0xd8, 0xd0, 0x50, 0x3d, 0xed, 0x04, 0xf4, 0x4a, 0xe6,
0xed, 0x2f, 0xe1, 0x05, 0x8b, 0xd6, 0x51, 0xc0, 0x86, 0x82, 0x4a, 0x69, 0xaa, 0x40, 0x09, 0xa7,
0xd3, 0xe6, 0x7f, 0xf2, 0xe0, 0xec, 0x85, 0xb1, 0x54, 0xb6, 0xb6, 0x7d, 0xb0, 0x8c, 0xbe, 0x84,
0x3b, 0xc4, 0xfc, 0x33, 0x11, 0xa6, 0x0b, 0x85, 0xe9, 0xbd, 0x6c, 0x56, 0x1f, 0x65, 0xba, 0x9b,
0x81, 0x93, 0x3e, 0xad, 0x53, 0xd0, 0x3e, 0xdd, 0x1c, 0xae, 0x92, 0x37, 0xbe, 0xa0, 0x13, 0xd8,
0xe0, 0xc2, 0x1b, 0x51, 0xa9, 0x92, 0xf2, 0x62, 0xff, 0x31, 0x32, 0xff, 0x3e, 0x9f, 0x2f, 0x02,
0xed, 0xdb, 0x9a, 0x44, 0xbb, 0xec, 0x03, 0x3d, 0x81, 0xbc, 0x20, 0xe7, 0x69, 0x1f, 0x99, 0xa9,
0x7c, 0x4c, 0xce, 0xd5, 0x92, 0x0b, 0xc3, 0x40, 0xbf, 0x05, 0xf0, 0x03, 0x19, 0x11, 0xe5, 0x8d,
0xa8, 0xb0, 0x27, 0x98, 0xb9, 0xc5, 0xee, 0x0c, 0xb5, 0xe4, 0x65, 0x81, 0x8d, 0x0e, 0xa1, 0xec,
0x91, 0x54, 0x83, 0x85, 0x9b, 0x7f, 0xbc, 0xf6, 0xda, 0xd6, 0x45, 0x55, 0xbb, 0xb8, 0xbe, 0xda,
0x2a, 0xa5, 0x16, 0x5c, 0xf2, 0x88, 0xd5, 0xe4, 0x21, 0x6c, 0xe8, 0x1f, 0xb2, 0x81, 0x4f, 0xcf,
0x49, 0x1c, 0xaa, 0xe4, 0xec, 0x6f, 0xa8, 0x15, 0xba, 0xbb, 0xef, 0x5a, 0x9c, 0x8d, 0xab, 0xa2,
0x16, 0x6c, 0xe8, 0xf7, 0x70, 0x87, 0x32, 0x4f, 0x4c, 0x8d, 0x02, 0xd3, 0x08, 0x4b, 0x37, 0x6f,
0xb6, 0x37, 0x03, 0x2f, 0x6d, 0xb6, 0x4a, 0xdf, 0xb0, 0x37, 0x03, 0x80, 0xa4, 0xfa, 0x7e, 0x58,
0xfd, 0x21, 0xc8, 0xfb, 0x44, 0x11, 0x23, 0xb9, 0x0a, 0x36, 0x63, 0xbd, 0x54, 0xb2, 0xe8, 0xff,
0x7d, 0xa9, 0x8e, 0xfb, 0xfa, 0x9b, 0xfa, 0xca, 0x3f, 0xbf, 0xa9, 0xaf, 0xfc, 0xe9, 0xba, 0x9e,
0x7b, 0x7d, 0x5d, 0xcf, 0xfd, 0xfd, 0xba, 0x9e, 0xfb, 0xd7, 0x75, 0x3d, 0x77, 0x56, 0x30, 0xed,
0xd1, 0x4f, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x90, 0x54, 0x3b, 0xfc, 0x57, 0x12, 0x00, 0x00,
}

View file

@ -197,6 +197,9 @@ message ContainerSpec {
// Groups specifies supplementary groups available to the user.
repeated string groups = 11;
// Privileges specifies security configuration/permissions.
Privileges privileges = 22;
// TTY declares that a TTY should be attached to the standard streams,
// including stdin if it is still open.
bool tty = 13 [(gogoproto.customname) = "TTY"];
@ -236,6 +239,10 @@ message ContainerSpec {
// will be exposed to the container.
repeated SecretReference secrets = 12;
// ConfigReference contains references to zero or more configs that
// will be exposed to the container.
repeated ConfigReference configs = 21;
// Hosts allow additional entries to be specified in /etc/hosts
// that associates IP addresses with hostnames.
// Detailed documentation is available in:
@ -371,3 +378,13 @@ message SecretSpec {
// Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes)
bytes data = 2;
}
// ConfigSpec specifies user-provided configuration files.
message ConfigSpec {
Annotations annotations = 1 [(gogoproto.nullable) = false];
// Data is the config payload - the maximum size is 500KB (that is, 500*1024 bytes)
// TODO(aaronl): Do we want to revise this to include multiple payloads in a single
// ConfigSpec? Define this to be a tar? etc...
bytes data = 2;
}

View file

@ -73,6 +73,7 @@ type Object struct {
// *Object_Secret
// *Object_Resource
// *Object_Extension
// *Object_Config
Object isObject_Object `protobuf_oneof:"Object"`
}
@ -110,6 +111,9 @@ type Object_Resource struct {
type Object_Extension struct {
Extension *Extension `protobuf:"bytes,8,opt,name=extension,oneof"`
}
type Object_Config struct {
Config *Config `protobuf:"bytes,9,opt,name=config,oneof"`
}
func (*Object_Node) isObject_Object() {}
func (*Object_Service) isObject_Object() {}
@ -119,6 +123,7 @@ func (*Object_Cluster) isObject_Object() {}
func (*Object_Secret) isObject_Object() {}
func (*Object_Resource) isObject_Object() {}
func (*Object_Extension) isObject_Object() {}
func (*Object_Config) isObject_Object() {}
func (m *Object) GetObject() isObject_Object {
if m != nil {
@ -183,6 +188,13 @@ func (m *Object) GetExtension() *Extension {
return nil
}
func (m *Object) GetConfig() *Config {
if x, ok := m.GetObject().(*Object_Config); ok {
return x.Config
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
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{}) {
return _Object_OneofMarshaler, _Object_OneofUnmarshaler, _Object_OneofSizer, []interface{}{
@ -194,6 +206,7 @@ func (*Object) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error,
(*Object_Secret)(nil),
(*Object_Resource)(nil),
(*Object_Extension)(nil),
(*Object_Config)(nil),
}
}
@ -241,6 +254,11 @@ func _Object_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if err := b.EncodeMessage(x.Extension); err != nil {
return err
}
case *Object_Config:
_ = b.EncodeVarint(9<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Config); err != nil {
return err
}
case nil:
default:
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)
err := b.DecodeMessage(msg)
m.Object = &Object_Extension{msg}
return true, err
case 9: // Object.config
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Config)
err := b.DecodeMessage(msg)
m.Object = &Object_Config{msg}
return true, err
default:
return false, nil
}
@ -364,6 +390,11 @@ func _Object_OneofSizer(msg proto.Message) (n int) {
n += proto.SizeVarint(8<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *Object_Config:
s := proto.Size(x.Config)
n += proto.SizeVarint(9<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
@ -412,6 +443,7 @@ type SelectBy struct {
// *SelectBy_Membership
// *SelectBy_ReferencedNetworkID
// *SelectBy_ReferencedSecretID
// *SelectBy_ReferencedConfigID
// *SelectBy_Kind
By isSelectBy_By `protobuf_oneof:"By"`
}
@ -468,6 +500,9 @@ type SelectBy_ReferencedNetworkID struct {
type SelectBy_ReferencedSecretID struct {
ReferencedSecretID string `protobuf:"bytes,14,opt,name=referenced_secret_id,json=referencedSecretId,proto3,oneof"`
}
type SelectBy_ReferencedConfigID struct {
ReferencedConfigID string `protobuf:"bytes,16,opt,name=referenced_config_id,json=referencedConfigId,proto3,oneof"`
}
type SelectBy_Kind struct {
Kind string `protobuf:"bytes,15,opt,name=kind,proto3,oneof"`
}
@ -486,6 +521,7 @@ func (*SelectBy_Role) isSelectBy_By() {}
func (*SelectBy_Membership) isSelectBy_By() {}
func (*SelectBy_ReferencedNetworkID) isSelectBy_By() {}
func (*SelectBy_ReferencedSecretID) isSelectBy_By() {}
func (*SelectBy_ReferencedConfigID) isSelectBy_By() {}
func (*SelectBy_Kind) isSelectBy_By() {}
func (m *SelectBy) GetBy() isSelectBy_By {
@ -593,6 +629,13 @@ func (m *SelectBy) GetReferencedSecretID() string {
return ""
}
func (m *SelectBy) GetReferencedConfigID() string {
if x, ok := m.GetBy().(*SelectBy_ReferencedConfigID); ok {
return x.ReferencedConfigID
}
return ""
}
func (m *SelectBy) GetKind() string {
if x, ok := m.GetBy().(*SelectBy_Kind); ok {
return x.Kind
@ -617,6 +660,7 @@ func (*SelectBy) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) erro
(*SelectBy_Membership)(nil),
(*SelectBy_ReferencedNetworkID)(nil),
(*SelectBy_ReferencedSecretID)(nil),
(*SelectBy_ReferencedConfigID)(nil),
(*SelectBy_Kind)(nil),
}
}
@ -673,6 +717,9 @@ func _SelectBy_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
case *SelectBy_ReferencedSecretID:
_ = b.EncodeVarint(14<<3 | proto.WireBytes)
_ = b.EncodeStringBytes(x.ReferencedSecretID)
case *SelectBy_ReferencedConfigID:
_ = b.EncodeVarint(16<<3 | proto.WireBytes)
_ = b.EncodeStringBytes(x.ReferencedConfigID)
case *SelectBy_Kind:
_ = b.EncodeVarint(15<<3 | proto.WireBytes)
_ = b.EncodeStringBytes(x.Kind)
@ -787,6 +834,13 @@ func _SelectBy_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffe
x, err := b.DecodeStringBytes()
m.By = &SelectBy_ReferencedSecretID{x}
return true, err
case 16: // By.referenced_config_id
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.By = &SelectBy_ReferencedConfigID{x}
return true, err
case 15: // By.kind
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
@ -859,6 +913,10 @@ func _SelectBy_OneofSizer(msg proto.Message) (n int) {
n += proto.SizeVarint(14<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.ReferencedSecretID)))
n += len(x.ReferencedSecretID)
case *SelectBy_ReferencedConfigID:
n += proto.SizeVarint(16<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.ReferencedConfigID)))
n += len(x.ReferencedConfigID)
case *SelectBy_Kind:
n += proto.SizeVarint(15<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Kind)))
@ -1034,6 +1092,12 @@ func (m *Object) CopyFrom(src interface{}) {
}
github_com_docker_swarmkit_api_deepcopy.Copy(v.Extension, o.GetExtension())
m.Object = &v
case *Object_Config:
v := Object_Config{
Config: &Config{},
}
github_com_docker_swarmkit_api_deepcopy.Copy(v.Config, o.GetConfig())
m.Object = &v
}
}
@ -1157,6 +1221,11 @@ func (m *SelectBy) CopyFrom(src interface{}) {
ReferencedSecretID: o.GetReferencedSecretID(),
}
m.By = &v
case *SelectBy_ReferencedConfigID:
v := SelectBy_ReferencedConfigID{
ReferencedConfigID: o.GetReferencedConfigID(),
}
m.By = &v
case *SelectBy_Kind:
v := SelectBy_Kind{
Kind: o.GetKind(),
@ -1513,6 +1582,20 @@ func (m *Object_Extension) MarshalTo(dAtA []byte) (int, error) {
}
return i, nil
}
func (m *Object_Config) MarshalTo(dAtA []byte) (int, error) {
i := 0
if m.Config != nil {
dAtA[i] = 0x4a
i++
i = encodeVarintStore(dAtA, i, uint64(m.Config.Size()))
n10, err := m.Config.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n10
}
return i, nil
}
func (m *SelectBySlot) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1594,11 +1677,11 @@ func (m *SelectBy) MarshalTo(dAtA []byte) (int, error) {
var l int
_ = l
if m.By != nil {
nn10, err := m.By.MarshalTo(dAtA[i:])
nn11, err := m.By.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += nn10
i += nn11
}
return i, nil
}
@ -1641,11 +1724,11 @@ func (m *SelectBy_Custom) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a
i++
i = encodeVarintStore(dAtA, i, uint64(m.Custom.Size()))
n11, err := m.Custom.MarshalTo(dAtA[i:])
n12, err := m.Custom.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n11
i += n12
}
return i, nil
}
@ -1655,11 +1738,11 @@ func (m *SelectBy_CustomPrefix) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x32
i++
i = encodeVarintStore(dAtA, i, uint64(m.CustomPrefix.Size()))
n12, err := m.CustomPrefix.MarshalTo(dAtA[i:])
n13, err := m.CustomPrefix.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n12
i += n13
}
return i, nil
}
@ -1685,11 +1768,11 @@ func (m *SelectBy_Slot) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x4a
i++
i = encodeVarintStore(dAtA, i, uint64(m.Slot.Size()))
n13, err := m.Slot.MarshalTo(dAtA[i:])
n14, err := m.Slot.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n13
i += n14
}
return i, nil
}
@ -1738,6 +1821,16 @@ func (m *SelectBy_Kind) MarshalTo(dAtA []byte) (int, error) {
i += copy(dAtA[i:], m.Kind)
return i, nil
}
func (m *SelectBy_ReferencedConfigID) MarshalTo(dAtA []byte) (int, error) {
i := 0
dAtA[i] = 0x82
i++
dAtA[i] = 0x1
i++
i = encodeVarintStore(dAtA, i, uint64(len(m.ReferencedConfigID)))
i += copy(dAtA[i:], m.ReferencedConfigID)
return i, nil
}
func (m *WatchRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1769,11 +1862,11 @@ func (m *WatchRequest) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintStore(dAtA, i, uint64(m.ResumeFrom.Size()))
n14, err := m.ResumeFrom.MarshalTo(dAtA[i:])
n15, err := m.ResumeFrom.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n14
i += n15
}
if m.IncludeOldObject {
dAtA[i] = 0x18
@ -1860,11 +1953,11 @@ func (m *WatchMessage) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintStore(dAtA, i, uint64(m.Version.Size()))
n15, err := m.Version.MarshalTo(dAtA[i:])
n16, err := m.Version.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n15
i += n16
}
return i, nil
}
@ -1893,21 +1986,21 @@ func (m *WatchMessage_Event) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintStore(dAtA, i, uint64(m.Object.Size()))
n16, err := m.Object.MarshalTo(dAtA[i:])
n17, err := m.Object.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n16
i += n17
}
if m.OldObject != nil {
dAtA[i] = 0x1a
i++
i = encodeVarintStore(dAtA, i, uint64(m.OldObject.Size()))
n17, err := m.OldObject.MarshalTo(dAtA[i:])
n18, err := m.OldObject.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n17
i += n18
}
return i, nil
}
@ -2144,6 +2237,15 @@ func (m *Object_Extension) Size() (n int) {
}
return n
}
func (m *Object_Config) Size() (n int) {
var l int
_ = l
if m.Config != nil {
l = m.Config.Size()
n += 1 + l + sovStore(uint64(l))
}
return n
}
func (m *SelectBySlot) Size() (n int) {
var l int
_ = l
@ -2292,6 +2394,13 @@ func (m *SelectBy_Kind) Size() (n int) {
n += 1 + l + sovStore(uint64(l))
return n
}
func (m *SelectBy_ReferencedConfigID) Size() (n int) {
var l int
_ = l
l = len(m.ReferencedConfigID)
n += 2 + l + sovStore(uint64(l))
return n
}
func (m *WatchRequest) Size() (n int) {
var l int
_ = l
@ -2466,6 +2575,16 @@ func (this *Object_Extension) String() string {
}, "")
return s
}
func (this *Object_Config) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Object_Config{`,
`Config:` + strings.Replace(fmt.Sprintf("%v", this.Config), "Config", "Config", 1) + `,`,
`}`,
}, "")
return s
}
func (this *SelectBySlot) String() string {
if this == nil {
return "nil"
@ -2649,6 +2768,16 @@ func (this *SelectBy_Kind) String() string {
}, "")
return s
}
func (this *SelectBy_ReferencedConfigID) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&SelectBy_ReferencedConfigID{`,
`ReferencedConfigID:` + fmt.Sprintf("%v", this.ReferencedConfigID) + `,`,
`}`,
}, "")
return s
}
func (this *WatchRequest) String() string {
if this == nil {
return "nil"
@ -2989,6 +3118,38 @@ func (m *Object) Unmarshal(dAtA []byte) error {
}
m.Object = &Object_Extension{v}
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStore
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthStore
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &Config{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Object = &Object_Config{v}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipStore(dAtA[iNdEx:])
@ -3691,6 +3852,35 @@ func (m *SelectBy) Unmarshal(dAtA []byte) error {
}
m.By = &SelectBy_Kind{string(dAtA[iNdEx:postIndex])}
iNdEx = postIndex
case 16:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ReferencedConfigID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowStore
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthStore
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.By = &SelectBy_ReferencedConfigID{string(dAtA[iNdEx:postIndex])}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipStore(dAtA[iNdEx:])
@ -4332,76 +4522,78 @@ var (
func init() { proto.RegisterFile("store.proto", fileDescriptorStore) }
var fileDescriptorStore = []byte{
// 1127 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x96, 0x4f, 0x6f, 0x1b, 0xc5,
0x1b, 0xc7, 0xbd, 0x8e, 0xb3, 0xb6, 0x1f, 0xc7, 0x6d, 0x34, 0x49, 0xdb, 0xfd, 0xf9, 0x57, 0x6c,
0x63, 0x04, 0x54, 0xb4, 0xb8, 0x10, 0x4a, 0x11, 0x50, 0x90, 0x62, 0xc7, 0xc8, 0xa6, 0x8a, 0x13,
0x8d, 0x93, 0xe6, 0x68, 0x6d, 0x76, 0x9f, 0xa4, 0x8b, 0xf7, 0x8f, 0x99, 0x1d, 0x3b, 0xcd, 0x8d,
0x23, 0xea, 0x1d, 0x89, 0x4b, 0xb9, 0xc0, 0x99, 0x0b, 0x37, 0x78, 0x03, 0x15, 0x07, 0xc4, 0x11,
0x2e, 0x16, 0xf5, 0x0b, 0xe0, 0x15, 0x70, 0x40, 0x33, 0x3b, 0x9b, 0x3f, 0xee, 0x3a, 0xa5, 0x27,
0xcf, 0xcc, 0x7e, 0x3f, 0xcf, 0x3e, 0xf3, 0x7c, 0x67, 0x1e, 0x2f, 0x14, 0x42, 0x1e, 0x30, 0xac,
0x0f, 0x59, 0xc0, 0x03, 0x42, 0xec, 0xc0, 0x1a, 0x20, 0xab, 0x87, 0x47, 0x26, 0xf3, 0x06, 0x0e,
0xaf, 0x8f, 0xdf, 0x2d, 0x15, 0xc2, 0x21, 0x5a, 0x61, 0x24, 0x28, 0x15, 0x83, 0xfd, 0x2f, 0xd0,
0xe2, 0xf1, 0xb4, 0xc0, 0x8f, 0x87, 0x18, 0x4f, 0x56, 0x0f, 0x83, 0xc3, 0x40, 0x0e, 0x6f, 0x8b,
0x91, 0x5a, 0x5d, 0x19, 0xba, 0xa3, 0x43, 0xc7, 0xbf, 0x1d, 0xfd, 0x44, 0x8b, 0xb5, 0xdf, 0x16,
0x40, 0xdf, 0x92, 0x91, 0x48, 0x1d, 0x32, 0x7e, 0x60, 0xa3, 0xa1, 0x55, 0xb5, 0x1b, 0x85, 0x35,
0xa3, 0xfe, 0x7c, 0x06, 0xf5, 0x6e, 0x60, 0x63, 0x3b, 0x45, 0xa5, 0x8e, 0x7c, 0x00, 0xd9, 0x10,
0xd9, 0xd8, 0xb1, 0xd0, 0x48, 0x4b, 0xe4, 0xff, 0x49, 0x48, 0x2f, 0x92, 0xb4, 0x53, 0x34, 0x56,
0x0b, 0xd0, 0x47, 0x7e, 0x14, 0xb0, 0x81, 0xb1, 0x30, 0x1f, 0xec, 0x46, 0x12, 0x01, 0x2a, 0xb5,
0xc8, 0x90, 0x9b, 0xe1, 0xc0, 0xc8, 0xcc, 0xcf, 0x70, 0xc7, 0x0c, 0x05, 0x22, 0x75, 0xe2, 0x45,
0x96, 0x3b, 0x0a, 0x39, 0x32, 0x63, 0x71, 0xfe, 0x8b, 0x9a, 0x91, 0x44, 0xbc, 0x48, 0xa9, 0xc9,
0x1d, 0xd0, 0x43, 0xb4, 0x18, 0x72, 0x43, 0x97, 0x5c, 0x29, 0x79, 0x67, 0x42, 0xd1, 0x4e, 0x51,
0xa5, 0x25, 0x1f, 0x41, 0x8e, 0x61, 0x18, 0x8c, 0x98, 0x85, 0x46, 0x56, 0x72, 0xd7, 0x93, 0x38,
0xaa, 0x34, 0xed, 0x14, 0x3d, 0xd1, 0x93, 0x4f, 0x20, 0x8f, 0x8f, 0x38, 0xfa, 0xa1, 0x13, 0xf8,
0x46, 0x4e, 0xc2, 0xaf, 0x24, 0xc1, 0xad, 0x58, 0xd4, 0x4e, 0xd1, 0x53, 0xa2, 0x91, 0x8b, 0x5d,
0xac, 0x6d, 0xc3, 0x52, 0x0f, 0x5d, 0xb4, 0x78, 0xe3, 0xb8, 0xe7, 0x06, 0x9c, 0xdc, 0x02, 0x50,
0x75, 0xef, 0x3b, 0xb6, 0xf4, 0x36, 0xdf, 0x28, 0x4e, 0x27, 0x95, 0xbc, 0x32, 0xa6, 0xb3, 0x41,
0xf3, 0x4a, 0xd0, 0xb1, 0x09, 0x81, 0x4c, 0xe8, 0x06, 0x5c, 0x1a, 0x9a, 0xa1, 0x72, 0x5c, 0xdb,
0x86, 0x4b, 0x71, 0xc4, 0xe6, 0x28, 0xe4, 0x81, 0x27, 0x54, 0x03, 0xc7, 0x57, 0xd1, 0xa8, 0x1c,
0x93, 0x55, 0x58, 0x74, 0x7c, 0x1b, 0x1f, 0x49, 0x34, 0x4f, 0xa3, 0x89, 0x58, 0x1d, 0x9b, 0xee,
0x08, 0xa5, 0xd1, 0x79, 0x1a, 0x4d, 0x6a, 0xdf, 0xe9, 0x90, 0x8b, 0x43, 0x12, 0x03, 0xd2, 0x27,
0x89, 0xe9, 0xd3, 0x49, 0x25, 0xdd, 0xd9, 0x68, 0xa7, 0x68, 0xda, 0xb1, 0xc9, 0x4d, 0xc8, 0x3b,
0x76, 0x7f, 0xc8, 0xf0, 0xc0, 0x51, 0x61, 0x1b, 0x4b, 0xd3, 0x49, 0x25, 0xd7, 0xd9, 0xd8, 0x96,
0x6b, 0xa2, 0x80, 0x8e, 0x1d, 0x8d, 0xc9, 0x2a, 0x64, 0x7c, 0xd3, 0x53, 0x2f, 0x92, 0x67, 0xd4,
0xf4, 0x90, 0xbc, 0x0a, 0x05, 0xf1, 0x1b, 0x07, 0xc9, 0xa8, 0x87, 0x20, 0x16, 0x15, 0x78, 0x0f,
0x74, 0x4b, 0x6e, 0x4b, 0x9d, 0x91, 0x5a, 0xb2, 0xd7, 0x67, 0x0b, 0x20, 0x3c, 0x8f, 0x18, 0xd2,
0x81, 0x62, 0x34, 0x8a, 0x5f, 0xa1, 0xbf, 0x44, 0x90, 0xa5, 0x08, 0x55, 0x89, 0xd4, 0xcf, 0x39,
0x95, 0x4d, 0x70, 0x4a, 0x78, 0x7e, 0xea, 0xd5, 0xeb, 0x90, 0x15, 0xf7, 0x50, 0x88, 0x73, 0x52,
0x0c, 0xd3, 0x49, 0x45, 0x17, 0x57, 0x54, 0x2a, 0x75, 0xf1, 0xb0, 0x63, 0x93, 0xbb, 0xca, 0xd2,
0xbc, 0x4c, 0xac, 0x7a, 0x51, 0x62, 0xe2, 0xc0, 0x88, 0xd2, 0x09, 0x3d, 0xd9, 0x80, 0xa2, 0x8d,
0xa1, 0xc3, 0xd0, 0xee, 0x87, 0xdc, 0xe4, 0x68, 0x40, 0x55, 0xbb, 0x71, 0x29, 0xf9, 0x54, 0x8a,
0x5b, 0xd7, 0x13, 0x22, 0xb1, 0x29, 0x45, 0xc9, 0x39, 0x59, 0x83, 0x0c, 0x0b, 0x5c, 0x34, 0x0a,
0x12, 0xbe, 0x3e, 0xaf, 0xa9, 0xd0, 0xc0, 0x95, 0x8d, 0x45, 0x68, 0x49, 0x07, 0xc0, 0x43, 0x6f,
0x1f, 0x59, 0xf8, 0xd0, 0x19, 0x1a, 0x4b, 0x92, 0x7c, 0x73, 0x1e, 0xd9, 0x1b, 0xa2, 0x55, 0xdf,
0x3c, 0x91, 0x0b, 0x73, 0x4f, 0x61, 0xb2, 0x09, 0x57, 0x18, 0x1e, 0x20, 0x43, 0xdf, 0x42, 0xbb,
0xaf, 0xfa, 0x88, 0xa8, 0x58, 0x51, 0x56, 0xec, 0xda, 0x74, 0x52, 0x59, 0xa1, 0x27, 0x02, 0xd5,
0x72, 0x64, 0xf9, 0x56, 0xd8, 0x73, 0xcb, 0x36, 0xf9, 0x1c, 0x56, 0xcf, 0x84, 0x8b, 0xae, 0xbd,
0x88, 0x76, 0x49, 0x46, 0xbb, 0x3a, 0x9d, 0x54, 0xc8, 0x69, 0xb4, 0xa8, 0x3f, 0xc8, 0x60, 0x84,
0xcd, 0xae, 0x8a, 0x0b, 0x13, 0x5d, 0xa2, 0xcb, 0xf1, 0x81, 0x15, 0xb3, 0x46, 0x06, 0xd2, 0x8d,
0xe3, 0xda, 0x9f, 0x69, 0x58, 0xda, 0x33, 0xb9, 0xf5, 0x90, 0xe2, 0x97, 0x23, 0x0c, 0x39, 0x69,
0x41, 0x16, 0x7d, 0xce, 0x1c, 0x0c, 0x0d, 0xad, 0xba, 0x70, 0xa3, 0xb0, 0x76, 0x33, 0xa9, 0x1e,
0x67, 0x91, 0x68, 0xd2, 0xf2, 0x39, 0x3b, 0xa6, 0x31, 0x4b, 0xee, 0x41, 0x81, 0x61, 0x38, 0xf2,
0xb0, 0x7f, 0xc0, 0x02, 0xef, 0xa2, 0xb6, 0xfd, 0x00, 0x99, 0x68, 0x2c, 0x14, 0x22, 0xfd, 0x67,
0x2c, 0xf0, 0xc8, 0x2d, 0x20, 0x8e, 0x6f, 0xb9, 0x23, 0x1b, 0xfb, 0x81, 0x6b, 0xf7, 0xa3, 0x3f,
0x20, 0x79, 0xe1, 0x72, 0x74, 0x59, 0x3d, 0xd9, 0x72, 0xed, 0xa8, 0x11, 0x95, 0xbe, 0xd1, 0x00,
0x4e, 0x73, 0x48, 0xec, 0x19, 0x1f, 0x83, 0x6e, 0x5a, 0x5c, 0x74, 0xbc, 0xb4, 0x34, 0xf9, 0xb5,
0xb9, 0x9b, 0x5a, 0x97, 0xb2, 0xfb, 0x8e, 0x6f, 0x53, 0x85, 0x90, 0xbb, 0x90, 0x3d, 0x70, 0x5c,
0x8e, 0x2c, 0x34, 0x16, 0x64, 0x49, 0xae, 0x5f, 0x74, 0xb4, 0x69, 0x2c, 0xae, 0xfd, 0x12, 0xd7,
0x76, 0x13, 0xc3, 0xd0, 0x3c, 0x44, 0xf2, 0x29, 0xe8, 0x38, 0x46, 0x9f, 0xc7, 0xa5, 0x7d, 0x63,
0x6e, 0x16, 0x8a, 0xa8, 0xb7, 0x84, 0x9c, 0x2a, 0x8a, 0xbc, 0x0f, 0xd9, 0x71, 0x54, 0xad, 0xff,
0x52, 0xd0, 0x58, 0x5b, 0xfa, 0x49, 0x83, 0x45, 0x19, 0xe8, 0x4c, 0x19, 0xb4, 0x97, 0x2f, 0xc3,
0x1a, 0xe8, 0xca, 0x88, 0xf4, 0xfc, 0xbf, 0xaa, 0xc8, 0x12, 0xaa, 0x94, 0xe4, 0x43, 0x80, 0x19,
0x03, 0x2f, 0xe6, 0xf2, 0x41, 0xec, 0xea, 0x5b, 0xff, 0x68, 0x70, 0x79, 0x26, 0x15, 0x72, 0x07,
0x56, 0xf7, 0xd6, 0x77, 0x9a, 0xed, 0xfe, 0x7a, 0x73, 0xa7, 0xb3, 0xd5, 0xed, 0xef, 0x76, 0xef,
0x77, 0xb7, 0xf6, 0xba, 0xcb, 0xa9, 0x52, 0xe9, 0xf1, 0x93, 0xea, 0xd5, 0x19, 0xf9, 0xae, 0x3f,
0xf0, 0x83, 0x23, 0x91, 0xf8, 0xca, 0x39, 0xaa, 0x49, 0x5b, 0xeb, 0x3b, 0xad, 0x65, 0xad, 0xf4,
0xbf, 0xc7, 0x4f, 0xaa, 0x57, 0x66, 0xa0, 0x26, 0xc3, 0xa8, 0x9b, 0x9c, 0x67, 0x76, 0xb7, 0x37,
0x04, 0x93, 0x4e, 0x64, 0x76, 0x87, 0x76, 0x12, 0x43, 0x5b, 0x9b, 0x5b, 0x0f, 0x5a, 0xcb, 0x99,
0x44, 0x86, 0xa2, 0x17, 0x8c, 0xb1, 0x74, 0xed, 0xeb, 0xef, 0xcb, 0xa9, 0x9f, 0x7f, 0x28, 0xcf,
0x6e, 0x75, 0xcd, 0x83, 0xc5, 0x9e, 0xf8, 0x4a, 0x23, 0x36, 0x2c, 0xca, 0x67, 0xa4, 0xfa, 0xa2,
0x8b, 0x58, 0xaa, 0xbe, 0xe8, 0x3c, 0xd5, 0xae, 0xfc, 0xfa, 0xe3, 0xdf, 0xdf, 0xa6, 0x2f, 0x43,
0x51, 0x2a, 0xde, 0xf6, 0x4c, 0xdf, 0x3c, 0x44, 0xf6, 0x8e, 0xd6, 0x30, 0x9e, 0x3e, 0x2b, 0xa7,
0xfe, 0x78, 0x56, 0x4e, 0x7d, 0x35, 0x2d, 0x6b, 0x4f, 0xa7, 0x65, 0xed, 0xf7, 0x69, 0x59, 0xfb,
0x6b, 0x5a, 0xd6, 0xf6, 0x75, 0xf9, 0xf9, 0xf6, 0xde, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa9,
0xa5, 0x8e, 0xe6, 0x35, 0x0a, 0x00, 0x00,
// 1160 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x96, 0xbd, 0x73, 0x1b, 0xc5,
0x1b, 0xc7, 0x75, 0x8a, 0x7c, 0x92, 0x1e, 0xd9, 0x89, 0x67, 0xed, 0x24, 0xf7, 0xd3, 0x2f, 0xc8,
0x42, 0x0c, 0x90, 0x21, 0x41, 0x01, 0x13, 0xc2, 0x00, 0x81, 0x19, 0x4b, 0x16, 0x23, 0x91, 0xf1,
0xcb, 0xac, 0xec, 0xa4, 0xd4, 0x5c, 0xee, 0x1e, 0x2b, 0x87, 0xee, 0x6e, 0xc5, 0xde, 0x49, 0x89,
0x3b, 0x0a, 0x0a, 0x26, 0x3d, 0x33, 0x34, 0xa9, 0xa0, 0xa6, 0xa1, 0x83, 0x7f, 0x20, 0x43, 0x45,
0x09, 0x8d, 0x86, 0xa8, 0xa4, 0xe0, 0x2f, 0xa0, 0x60, 0xf6, 0xe5, 0xfc, 0xa2, 0x9c, 0x1c, 0x52,
0x69, 0x77, 0xef, 0xf3, 0x7d, 0xf6, 0xb9, 0xe7, 0xed, 0x04, 0xa5, 0x28, 0x66, 0x1c, 0xeb, 0x43,
0xce, 0x62, 0x46, 0x88, 0xcb, 0x9c, 0x01, 0xf2, 0x7a, 0xf4, 0xd0, 0xe6, 0xc1, 0xc0, 0x8b, 0xeb,
0xe3, 0x77, 0xcb, 0xa5, 0x68, 0x88, 0x4e, 0xa4, 0x80, 0xf2, 0x12, 0xbb, 0xff, 0x05, 0x3a, 0x71,
0xb2, 0x2d, 0xc5, 0x87, 0x43, 0x4c, 0x36, 0xab, 0x7d, 0xd6, 0x67, 0x72, 0x79, 0x43, 0xac, 0xf4,
0xe9, 0xca, 0xd0, 0x1f, 0xf5, 0xbd, 0xf0, 0x86, 0xfa, 0x51, 0x87, 0xb5, 0xaf, 0x73, 0x60, 0xee,
0x48, 0x4b, 0xa4, 0x0e, 0xb9, 0x90, 0xb9, 0x68, 0x19, 0x55, 0xe3, 0x6a, 0x69, 0xdd, 0xaa, 0x3f,
0xef, 0x41, 0x7d, 0x9b, 0xb9, 0xd8, 0xce, 0x50, 0xc9, 0x91, 0x0f, 0x20, 0x1f, 0x21, 0x1f, 0x7b,
0x0e, 0x5a, 0x59, 0x29, 0xf9, 0x7f, 0x9a, 0xa4, 0xab, 0x90, 0x76, 0x86, 0x26, 0xb4, 0x10, 0x86,
0x18, 0x3f, 0x64, 0x7c, 0x60, 0x9d, 0x9b, 0x2f, 0xdc, 0x56, 0x88, 0x10, 0x6a, 0x5a, 0x78, 0x18,
0xdb, 0xd1, 0xc0, 0xca, 0xcd, 0xf7, 0x70, 0xcf, 0x8e, 0x84, 0x44, 0x72, 0xe2, 0x22, 0xc7, 0x1f,
0x45, 0x31, 0x72, 0x6b, 0x61, 0xfe, 0x45, 0x4d, 0x85, 0x88, 0x8b, 0x34, 0x4d, 0x6e, 0x82, 0x19,
0xa1, 0xc3, 0x31, 0xb6, 0x4c, 0xa9, 0x2b, 0xa7, 0xbf, 0x99, 0x20, 0xda, 0x19, 0xaa, 0x59, 0xf2,
0x11, 0x14, 0x38, 0x46, 0x6c, 0xc4, 0x1d, 0xb4, 0xf2, 0x52, 0x77, 0x25, 0x4d, 0x47, 0x35, 0xd3,
0xce, 0xd0, 0x23, 0x9e, 0x7c, 0x02, 0x45, 0x7c, 0x14, 0x63, 0x18, 0x79, 0x2c, 0xb4, 0x0a, 0x52,
0xfc, 0x4a, 0x9a, 0xb8, 0x95, 0x40, 0xed, 0x0c, 0x3d, 0x56, 0x08, 0x87, 0x1d, 0x16, 0x1e, 0x78,
0x7d, 0xab, 0x38, 0xdf, 0xe1, 0xa6, 0x24, 0x84, 0xc3, 0x8a, 0x6d, 0x14, 0x92, 0xdc, 0xd7, 0x76,
0x61, 0xb1, 0x8b, 0x3e, 0x3a, 0x71, 0xe3, 0xb0, 0xeb, 0xb3, 0x98, 0x5c, 0x07, 0xd0, 0xd9, 0xea,
0x79, 0xae, 0xac, 0x88, 0x62, 0x63, 0x69, 0x3a, 0x59, 0x2b, 0xea, 0x74, 0x76, 0x36, 0x69, 0x51,
0x03, 0x1d, 0x97, 0x10, 0xc8, 0x45, 0x3e, 0x8b, 0x65, 0x19, 0xe4, 0xa8, 0x5c, 0xd7, 0x76, 0xe1,
0x7c, 0x62, 0xb1, 0x39, 0x8a, 0x62, 0x16, 0x08, 0x6a, 0xe0, 0x85, 0xda, 0x1a, 0x95, 0x6b, 0xb2,
0x0a, 0x0b, 0x5e, 0xe8, 0xe2, 0x23, 0x29, 0x2d, 0x52, 0xb5, 0x11, 0xa7, 0x63, 0xdb, 0x1f, 0xa1,
0x2c, 0x8f, 0x22, 0x55, 0x9b, 0xda, 0x5f, 0x26, 0x14, 0x12, 0x93, 0xc4, 0x82, 0xec, 0x91, 0x63,
0xe6, 0x74, 0xb2, 0x96, 0xed, 0x6c, 0xb6, 0x33, 0x34, 0xeb, 0xb9, 0xe4, 0x1a, 0x14, 0x3d, 0xb7,
0x37, 0xe4, 0x78, 0xe0, 0x69, 0xb3, 0x8d, 0xc5, 0xe9, 0x64, 0xad, 0xd0, 0xd9, 0xdc, 0x95, 0x67,
0x22, 0xec, 0x9e, 0xab, 0xd6, 0x64, 0x15, 0x72, 0xa1, 0x1d, 0xe8, 0x8b, 0x64, 0x65, 0xdb, 0x01,
0x92, 0x57, 0xa1, 0x24, 0x7e, 0x13, 0x23, 0x39, 0xfd, 0x10, 0xc4, 0xa1, 0x16, 0xde, 0x06, 0xd3,
0x91, 0xaf, 0xa5, 0x2b, 0xab, 0x96, 0x5e, 0x21, 0x27, 0x03, 0x20, 0x03, 0xaf, 0x42, 0xd1, 0x81,
0x25, 0xb5, 0x4a, 0xae, 0x30, 0x5f, 0xc2, 0xc8, 0xa2, 0x92, 0x6a, 0x47, 0xea, 0xa7, 0x32, 0x95,
0x4f, 0xc9, 0x94, 0xa8, 0x94, 0xe3, 0x5c, 0xbd, 0x0e, 0x79, 0xd1, 0xbd, 0x02, 0x2e, 0x48, 0x18,
0xa6, 0x93, 0x35, 0x53, 0x34, 0xb6, 0x24, 0x4d, 0xf1, 0xb0, 0xe3, 0x92, 0x5b, 0x3a, 0xa5, 0xaa,
0x9c, 0xaa, 0x67, 0x39, 0x26, 0x0a, 0x46, 0x84, 0x4e, 0xf0, 0x64, 0x13, 0x96, 0x5c, 0x8c, 0x3c,
0x8e, 0x6e, 0x2f, 0x8a, 0xed, 0x18, 0x2d, 0xa8, 0x1a, 0x57, 0xcf, 0xa7, 0xd7, 0xb2, 0xe8, 0xd5,
0xae, 0x80, 0xc4, 0x4b, 0x69, 0x95, 0xdc, 0x93, 0x75, 0xc8, 0x71, 0xe6, 0xa3, 0x55, 0x92, 0xe2,
0x2b, 0xf3, 0x46, 0x11, 0x65, 0xbe, 0x1c, 0x47, 0x82, 0x25, 0x1d, 0x80, 0x00, 0x83, 0xfb, 0xc8,
0xa3, 0x07, 0xde, 0xd0, 0x5a, 0x94, 0xca, 0x37, 0xe7, 0x29, 0xbb, 0x43, 0x74, 0xea, 0x5b, 0x47,
0xb8, 0x48, 0xee, 0xb1, 0x98, 0x6c, 0xc1, 0x45, 0x8e, 0x07, 0xc8, 0x31, 0x74, 0xd0, 0xed, 0xe9,
0xe9, 0x23, 0x22, 0xb6, 0x24, 0x23, 0x76, 0x79, 0x3a, 0x59, 0x5b, 0xa1, 0x47, 0x80, 0x1e, 0x54,
0x32, 0x7c, 0x2b, 0xfc, 0xb9, 0x63, 0x97, 0x7c, 0x0e, 0xab, 0x27, 0xcc, 0xa9, 0x61, 0x21, 0xac,
0x9d, 0x97, 0xd6, 0x2e, 0x4d, 0x27, 0x6b, 0xe4, 0xd8, 0x9a, 0x9a, 0x2a, 0xd2, 0x18, 0xe1, 0xb3,
0xa7, 0xa2, 0x61, 0x54, 0x13, 0x5d, 0x48, 0x0a, 0x56, 0xb6, 0xd1, 0xe9, 0x1b, 0x54, 0x77, 0x8b,
0x1b, 0x96, 0xd3, 0x6e, 0x50, 0x63, 0x60, 0xf6, 0x06, 0x7d, 0xea, 0x36, 0x72, 0x90, 0x6d, 0x1c,
0xd6, 0xfe, 0xc8, 0xc2, 0xe2, 0x3d, 0x3b, 0x76, 0x1e, 0x50, 0xfc, 0x72, 0x84, 0x51, 0x4c, 0x5a,
0x90, 0xc7, 0x30, 0xe6, 0x1e, 0x46, 0x96, 0x51, 0x3d, 0x77, 0xb5, 0xb4, 0x7e, 0x2d, 0x2d, 0xb6,
0x27, 0x25, 0x6a, 0xd3, 0x0a, 0x63, 0x7e, 0x48, 0x13, 0x2d, 0xb9, 0x0d, 0x25, 0x8e, 0xd1, 0x28,
0xc0, 0xde, 0x01, 0x67, 0xc1, 0x59, 0x1f, 0x8e, 0xbb, 0xc8, 0xc5, 0x68, 0xa3, 0xa0, 0xf8, 0xcf,
0x38, 0x0b, 0xc8, 0x75, 0x20, 0x5e, 0xe8, 0xf8, 0x23, 0x17, 0x7b, 0xcc, 0x77, 0x7b, 0xea, 0x13,
0x28, 0x9b, 0xb7, 0x40, 0x97, 0xf5, 0x93, 0x1d, 0xdf, 0x55, 0x43, 0xad, 0xfc, 0xad, 0x01, 0x70,
0xec, 0x43, 0xea, 0xfc, 0xf9, 0x18, 0x4c, 0xdb, 0x89, 0xc5, 0xcc, 0xcd, 0xca, 0x82, 0x79, 0x6d,
0xee, 0x4b, 0x6d, 0x48, 0xec, 0x8e, 0x17, 0xba, 0x54, 0x4b, 0xc8, 0x2d, 0xc8, 0x1f, 0x78, 0x7e,
0x8c, 0x3c, 0xb2, 0xce, 0xc9, 0x90, 0x5c, 0x39, 0xab, 0x4d, 0x68, 0x02, 0xd7, 0x7e, 0x49, 0x62,
0xbb, 0x85, 0x51, 0x64, 0xf7, 0x91, 0x7c, 0x0a, 0x26, 0x8e, 0x31, 0x8c, 0x93, 0xd0, 0xbe, 0x31,
0xd7, 0x0b, 0xad, 0xa8, 0xb7, 0x04, 0x4e, 0xb5, 0x8a, 0xbc, 0x0f, 0xf9, 0xb1, 0x8a, 0xd6, 0x7f,
0x09, 0x68, 0xc2, 0x96, 0x7f, 0x32, 0x60, 0x41, 0x1a, 0x3a, 0x11, 0x06, 0xe3, 0xe5, 0xc3, 0xb0,
0x0e, 0xa6, 0x4e, 0x44, 0x76, 0xfe, 0xb7, 0x47, 0xa5, 0x84, 0x6a, 0x92, 0x7c, 0x08, 0x30, 0x93,
0xc0, 0xb3, 0x75, 0x45, 0x96, 0x64, 0xf5, 0xad, 0x7f, 0x0c, 0xb8, 0x30, 0xe3, 0x0a, 0xb9, 0x09,
0xab, 0xf7, 0x36, 0xf6, 0x9a, 0xed, 0xde, 0x46, 0x73, 0xaf, 0xb3, 0xb3, 0xdd, 0xdb, 0xdf, 0xbe,
0xb3, 0xbd, 0x73, 0x6f, 0x7b, 0x39, 0x53, 0x2e, 0x3f, 0x7e, 0x52, 0xbd, 0x34, 0x83, 0xef, 0x87,
0x83, 0x90, 0x3d, 0x14, 0x8e, 0xaf, 0x9c, 0x52, 0x35, 0x69, 0x6b, 0x63, 0xaf, 0xb5, 0x6c, 0x94,
0xff, 0xf7, 0xf8, 0x49, 0xf5, 0xe2, 0x8c, 0xa8, 0xc9, 0x51, 0x4d, 0xa6, 0xd3, 0x9a, 0xfd, 0xdd,
0x4d, 0xa1, 0xc9, 0xa6, 0x6a, 0xf6, 0x87, 0x6e, 0x9a, 0x86, 0xb6, 0xb6, 0x76, 0xee, 0xb6, 0x96,
0x73, 0xa9, 0x1a, 0x8a, 0x01, 0x1b, 0x63, 0xf9, 0xf2, 0x37, 0xdf, 0x57, 0x32, 0x3f, 0xff, 0x50,
0x99, 0x7d, 0xd5, 0xf5, 0x00, 0x16, 0xba, 0xe2, 0x7f, 0x22, 0x71, 0x61, 0x41, 0x3e, 0x23, 0xd5,
0x17, 0x35, 0x62, 0xb9, 0xfa, 0xa2, 0x7a, 0xaa, 0x5d, 0xfc, 0xf5, 0xc7, 0xbf, 0xbf, 0xcb, 0x5e,
0x80, 0x25, 0x49, 0xbc, 0x1d, 0xd8, 0xa1, 0xdd, 0x47, 0xfe, 0x8e, 0xd1, 0xb0, 0x9e, 0x3e, 0xab,
0x64, 0x7e, 0x7f, 0x56, 0xc9, 0x7c, 0x35, 0xad, 0x18, 0x4f, 0xa7, 0x15, 0xe3, 0xb7, 0x69, 0xc5,
0xf8, 0x73, 0x5a, 0x31, 0xee, 0x9b, 0xf2, 0x0f, 0xe4, 0x7b, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff,
0x9d, 0xb1, 0x59, 0x21, 0xb7, 0x0a, 0x00, 0x00,
}

View file

@ -18,6 +18,7 @@ message Object {
Secret secret = 6;
Resource resource = 7;
Extension extension = 8;
Config config = 9;
}
}
@ -60,6 +61,7 @@ message SelectBy {
// supported by: service, task
string referenced_network_id = 13 [(gogoproto.customname) = "ReferencedNetworkID"];
string referenced_secret_id = 14 [(gogoproto.customname) = "ReferencedSecretID"];
string referenced_config_id = 16 [(gogoproto.customname) = "ReferencedConfigID"];
// supported by: resource
string kind = 15;

File diff suppressed because it is too large Load diff

View file

@ -86,6 +86,18 @@ message NodeDescription {
// Information about the Docker Engine on the node.
EngineDescription engine = 4;
// Information on the node's TLS setup
NodeTLSInfo tls_info = 5 [(gogoproto.customname) = "TLSInfo"];
}
message NodeTLSInfo {
// Information about which root certs the node trusts
bytes trust_root = 1;
// Information about the node's current TLS certificate
bytes cert_issuer_subject = 2;
bytes cert_issuer_public_key = 3;
}
message RaftMemberStatus {
@ -853,6 +865,20 @@ message ManagerStatus {
RaftMemberStatus.Reachability reachability = 4;
}
// FileTarget represents a specific target that is backed by a file
message FileTarget {
// Name represents the final filename in the filesystem
string name = 1;
// UID represents the file UID
string uid = 2 [(gogoproto.customname) = "UID"];
// GID represents the file GID
string gid = 3 [(gogoproto.customname) = "GID"];
// Mode represents the FileMode of the file
uint32 mode = 4 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false];
}
// SecretReference is the linkage between a service and a secret that it uses.
message SecretReference {
@ -865,20 +891,21 @@ message SecretReference {
// lookup/display purposes. The secret in the reference will be identified by its ID.
string secret_name = 2;
// FileTarget represents a specific target that is backed by a file
message FileTarget {
// Name represents the final filename in the filesystem
string name = 1;
// UID represents the file UID
string uid = 2 [(gogoproto.customname) = "UID"];
// GID represents the file GID
string gid = 3 [(gogoproto.customname) = "GID"];
// Mode represents the FileMode of the file
uint32 mode = 4 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false];
// Target specifies how this secret should be exposed to the task.
oneof target {
FileTarget file = 3;
}
}
// ConfigReference is the linkage between a service and a config that it uses.
message ConfigReference {
// ConfigID represents the ID of the specific Config that we're
// referencing.
string config_id = 1;
// ConfigName is the name of the config that this references, but this is just provided for
// lookup/display purposes. The config in the reference will be identified by its ID.
string config_name = 2;
// Target specifies how this secret should be exposed to the task.
oneof target {
@ -943,3 +970,26 @@ message RootRotation {
// cross-signed CA cert is the CACert that has been cross-signed by the previous root
bytes cross_signed_ca_cert = 3 [(gogoproto.customname) = "CrossSignedCACert"];
}
// Privileges specifies security configuration/permissions.
message Privileges {
// CredentialSpec for managed service account (Windows only).
message CredentialSpec {
oneof source {
string file = 1;
string registry = 2;
}
}
CredentialSpec credential_spec = 1;
// SELinuxContext contains the SELinux labels for the container.
message SELinuxContext {
bool disable = 1;
string user = 2;
string role = 3;
string type = 4;
string level = 5;
}
SELinuxContext selinux_context = 2 [(gogoproto.customname) = "SELinuxContext"];
}

View file

@ -104,6 +104,12 @@ type CertPaths struct {
Cert, Key string
}
// IssuerInfo contains the subject and public key of the issuer of a certificate
type IssuerInfo struct {
Subject []byte
PublicKey []byte
}
// LocalSigner is a signer that can sign CSRs
type LocalSigner struct {
cfsigner.Signer
@ -192,39 +198,47 @@ func (rca *RootCA) Signer() (*LocalSigner, error) {
}
// IssueAndSaveNewCertificates generates a new key-pair, signs it with the local root-ca, and returns a
// tls certificate
func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, error) {
// TLS certificate and the issuer information for the certificate.
func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, *IssuerInfo, error) {
csr, key, err := GenerateNewCSR()
if err != nil {
return nil, errors.Wrap(err, "error when generating new node certs")
return nil, nil, errors.Wrap(err, "error when generating new node certs")
}
// Obtain a signed Certificate
certChain, err := rca.ParseValidateAndSignCSR(csr, cn, ou, org)
if err != nil {
return nil, errors.Wrap(err, "failed to sign node certificate")
return nil, nil, errors.Wrap(err, "failed to sign node certificate")
}
signer, err := rca.Signer()
if err != nil { // should never happen, since if ParseValidateAndSignCSR did not fail this root CA must have a signer
return nil, nil, err
}
// Create a valid TLSKeyPair out of the PEM encoded private key and certificate
tlsKeyPair, err := tls.X509KeyPair(certChain, key)
if err != nil {
return nil, err
return nil, nil, err
}
if err := kw.Write(certChain, key, nil); err != nil {
return nil, err
if err := kw.Write(NormalizePEMs(certChain), key, nil); err != nil {
return nil, nil, err
}
return &tlsKeyPair, nil
return &tlsKeyPair, &IssuerInfo{
PublicKey: signer.parsedCert.RawSubjectPublicKeyInfo,
Subject: signer.parsedCert.RawSubject,
}, nil
}
// RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is
// available, or by requesting them from the remote server at remoteAddr.
func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, error) {
// available, or by requesting them from the remote server at remoteAddr. This function returns the TLS
// certificate and the issuer information for the certificate.
func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, *IssuerInfo, error) {
// Create a new key/pair and CSR
csr, key, err := GenerateNewCSR()
if err != nil {
return nil, errors.Wrap(err, "error when generating new node certs")
return nil, nil, errors.Wrap(err, "error when generating new node certs")
}
// 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
config.ForceRemote = true
}
if err != nil {
return nil, err
return nil, nil, err
}
// Доверяй, но проверяй.
// Before we overwrite our local key + certificate, let's make sure the server gave us one that is valid
// Create an X509Cert so we can .Verify()
// Check to see if this certificate was signed by our CA, and isn't expired
parsedCerts, err := ValidateCertChain(rca.Pool, signedCert, false)
parsedCerts, chains, err := ValidateCertChain(rca.Pool, signedCert, false)
if err != nil {
return nil, err
return nil, nil, err
}
// ValidateChain, if successful, will always return at least 1 parsed cert and at least 1 chain containing
// at least 2 certificates: the leaf and the root.
leafCert := parsedCerts[0]
issuer := chains[0][1]
// Create a valid TLSKeyPair out of the PEM encoded private key and certificate
tlsKeyPair, err := tls.X509KeyPair(signedCert, key)
if err != nil {
return nil, err
return nil, nil, err
}
var kekUpdate *KEKData
for i := 0; i < 5; i++ {
// ValidateCertChain will always return at least 1 cert, so indexing at 0 is safe
kekUpdate, err = rca.getKEKUpdate(ctx, parsedCerts[0], tlsKeyPair, config.ConnBroker)
kekUpdate, err = rca.getKEKUpdate(ctx, leafCert, tlsKeyPair, config.ConnBroker)
if err == nil {
break
}
}
if err != nil {
return nil, err
return nil, nil, err
}
if err := kw.Write(signedCert, key, kekUpdate); err != nil {
return nil, err
if err := kw.Write(NormalizePEMs(signedCert), key, kekUpdate); err != nil {
return nil, nil, err
}
return &tlsKeyPair, nil
return &tlsKeyPair, &IssuerInfo{
PublicKey: issuer.RawSubjectPublicKeyInfo,
Subject: issuer.RawSubject,
}, nil
}
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
var intermediatePool *x509.CertPool
var parsedIntermediates []*x509.Certificate
if len(intermediates) > 0 {
parsedIntermediates, err = ValidateCertChain(pool, intermediates, false)
parsedIntermediates, _, err = ValidateCertChain(pool, intermediates, false)
if err != nil {
return RootCA{}, errors.Wrap(err, "invalid intermediate chain")
}
@ -469,15 +491,15 @@ func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry tim
// intermediate pool), because this function is intended to be used when reading certs from untrusted locations such as
// from disk or over a network when a CSR is signed, so it is extra pedantic.
// This function always returns all the parsed certificates in the bundle in order, which means there will always be
// at least 1 certificate if there is no error.
func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, error) {
// at least 1 certificate if there is no error, and the valid chains found by Certificate.Verify
func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, [][]*x509.Certificate, error) {
// Parse all the certificates in the cert bundle
parsedCerts, err := helpers.ParseCertificatesPEM(certs)
if err != nil {
return nil, err
return nil, nil, err
}
if len(parsedCerts) == 0 {
return nil, errors.New("no certificates to validate")
return nil, nil, errors.New("no certificates to validate")
}
now := time.Now()
// 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)
// Manual expiry validation because we want more information on which certificate in the chain is expired, and
// because this is an easier way to allow expired certs.
if now.Before(cert.NotBefore) {
return nil, errors.Wrapf(
return nil, nil, errors.Wrapf(
x509.CertificateInvalidError{
Cert: cert,
Reason: x509.Expired,
@ -495,7 +517,7 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
i+1, cert.Subject.CommonName, cert.NotBefore.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
}
if !allowExpired && now.After(cert.NotAfter) {
return nil, errors.Wrapf(
return nil, nil, errors.Wrapf(
x509.CertificateInvalidError{
Cert: cert,
Reason: x509.Expired,
@ -508,7 +530,7 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
// check that the previous cert was signed by this cert
prevCert := parsedCerts[i-1]
if err := prevCert.CheckSignatureFrom(cert); err != nil {
return nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
return nil, nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
i, prevCert.Subject.CommonName, i+1, cert.Subject.CommonName)
}
@ -526,6 +548,8 @@ func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool)
CurrentTime: now,
}
var chains [][]*x509.Certificate
// If we accept expired certs, try to build a valid cert chain using some subset of the certs. We start off using the
// first certificate's NotAfter as the current time, thus ensuring that the first cert is not expired. If the chain
// 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)
}
verifyOpts.CurrentTime = cert.NotAfter
_, err = parsedCerts[0].Verify(verifyOpts)
chains, err = parsedCerts[0].Verify(verifyOpts)
if err == nil {
return parsedCerts, nil
return parsedCerts, chains, nil
}
}
if invalid, ok := err.(x509.CertificateInvalidError); ok && invalid.Reason == x509.Expired {
return nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
return nil, nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
}
return nil, err
return nil, nil, err
}
_, err = parsedCerts[0].Verify(verifyOpts)
chains, err = parsedCerts[0].Verify(verifyOpts)
if err != nil {
return nil, err
return nil, nil, err
}
return parsedCerts, nil
return parsedCerts, chains, nil
}
// 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) {
return pem.EncodeToMemory(encryptedPEMBlock), nil
}
// NormalizePEMs takes a bundle of PEM-encoded certificates in a certificate bundle,
// decodes them, removes headers, and re-encodes them to make sure that they have
// consistent whitespace. Note that this is intended to normalize x509 certificates
// in PEM format, hence the stripping out of headers.
func NormalizePEMs(certs []byte) []byte {
var (
results []byte
pemBlock *pem.Block
)
for {
pemBlock, certs = pem.Decode(bytes.TrimSpace(certs))
if pemBlock == nil {
return results
}
pemBlock.Headers = nil
results = append(results, pem.EncodeToMemory(pemBlock)...)
}
}

View file

@ -19,6 +19,7 @@ import (
"github.com/docker/swarmkit/connectionbroker"
"github.com/docker/swarmkit/identity"
"github.com/docker/swarmkit/log"
"github.com/docker/swarmkit/watch"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"google.golang.org/grpc/credentials"
@ -71,10 +72,16 @@ type SecurityConfig struct {
externalCA *ExternalCA
keyReadWriter *KeyReadWriter
certificate *tls.Certificate
issuerInfo *IssuerInfo
externalCAClientRootPool *x509.CertPool
ServerTLSCreds *MutableTLSCreds
ClientTLSCreds *MutableTLSCreds
// An optional queue for anyone interested in subscribing to SecurityConfig updates
queue *watch.Queue
}
// CertificateUpdate represents a change in the underlying TLS configuration being returned by
@ -85,25 +92,41 @@ type CertificateUpdate struct {
}
// NewSecurityConfig initializes and returns a new SecurityConfig.
func NewSecurityConfig(rootCA *RootCA, krw *KeyReadWriter, clientTLSCreds, serverTLSCreds *MutableTLSCreds) *SecurityConfig {
func NewSecurityConfig(rootCA *RootCA, krw *KeyReadWriter, tlsKeyPair *tls.Certificate, issuerInfo *IssuerInfo) (*SecurityConfig, error) {
// Create the Server TLS Credentials for this node. These will not be used by workers.
serverTLSCreds, err := rootCA.NewServerTLSCredentials(tlsKeyPair)
if err != nil {
return nil, err
}
// Create a TLSConfig to be used when this node connects as a client to another remote node.
// We're using ManagerRole as remote serverName for TLS host verification because both workers
// and managers always connect to remote managers.
clientTLSCreds, err := rootCA.NewClientTLSCredentials(tlsKeyPair, ManagerRole)
if err != nil {
return nil, err
}
// Make a new TLS config for the external CA client without a
// ServerName value set.
clientTLSConfig := clientTLSCreds.Config()
externalCATLSConfig := &tls.Config{
Certificates: clientTLSConfig.Certificates,
RootCAs: clientTLSConfig.RootCAs,
Certificates: []tls.Certificate{*tlsKeyPair},
RootCAs: rootCA.Pool,
MinVersion: tls.VersionTLS12,
}
return &SecurityConfig{
rootCA: rootCA,
keyReadWriter: krw,
rootCA: rootCA,
keyReadWriter: krw,
certificate: tlsKeyPair,
issuerInfo: issuerInfo,
externalCA: NewExternalCA(rootCA, externalCATLSConfig),
ClientTLSCreds: clientTLSCreds,
ServerTLSCreds: serverTLSCreds,
externalCAClientRootPool: rootCA.Pool,
}
}, nil
}
// RootCA returns the root CA.
@ -136,19 +159,32 @@ func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA, externalCARootPool *x509.C
s.rootCA = rootCA
s.externalCAClientRootPool = externalCARootPool
clientTLSConfig := s.ClientTLSCreds.Config()
return s.updateTLSCredentials(clientTLSConfig.Certificates)
return s.updateTLSCredentials(s.certificate, s.issuerInfo)
}
// updateTLSCredentials updates the client, server, and TLS credentials on a security config. This function expects
// something else to have taken out a lock on the SecurityConfig.
func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) error {
clientConfig, err := NewClientTLSConfig(certificates, s.rootCA.Pool, ManagerRole)
// SetWatch allows you to set a watch on the security config, in order to be notified of any changes
func (s *SecurityConfig) SetWatch(q *watch.Queue) {
s.mu.Lock()
defer s.mu.Unlock()
s.queue = q
}
// IssuerInfo returns the issuer subject and issuer public key
func (s *SecurityConfig) IssuerInfo() *IssuerInfo {
s.mu.Lock()
defer s.mu.Unlock()
return s.issuerInfo
}
// This function expects something else to have taken out a lock on the SecurityConfig.
func (s *SecurityConfig) updateTLSCredentials(certificate *tls.Certificate, issuerInfo *IssuerInfo) error {
certs := []tls.Certificate{*certificate}
clientConfig, err := NewClientTLSConfig(certs, s.rootCA.Pool, ManagerRole)
if err != nil {
return errors.Wrap(err, "failed to create a new client config using the new root CA")
}
serverConfig, err := NewServerTLSConfig(certificates, s.rootCA.Pool)
serverConfig, err := NewServerTLSConfig(certs, s.rootCA.Pool)
if err != nil {
return errors.Wrap(err, "failed to create a new server config using the new root CA")
}
@ -160,7 +196,7 @@ func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) er
// Update the external CA to use the new client TLS
// config using a copy without a serverName specified.
s.externalCA.UpdateTLSConfig(&tls.Config{
Certificates: certificates,
Certificates: certs,
RootCAs: s.externalCAClientRootPool,
MinVersion: tls.VersionTLS12,
})
@ -169,6 +205,15 @@ func (s *SecurityConfig) updateTLSCredentials(certificates []tls.Certificate) er
return errors.Wrap(err, "failed to update the server TLS credentials")
}
s.certificate = certificate
s.issuerInfo = issuerInfo
if s.queue != nil {
s.queue.Publish(&api.NodeTLSInfo{
TrustRoot: s.rootCA.Certs,
CertIssuerPublicKey: s.issuerInfo.PublicKey,
CertIssuerSubject: s.issuerInfo.Subject,
})
}
return nil
}
@ -300,9 +345,13 @@ func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter,
}
// Check to see if this certificate was signed by our CA, and isn't expired
if _, err := ValidateCertChain(rootCA.Pool, cert, allowExpired); err != nil {
_, chains, err := ValidateCertChain(rootCA.Pool, cert, allowExpired)
if err != nil {
return nil, err
}
// ValidateChain, if successful, will always return at least 1 chain containing
// at least 2 certificates: the leaf and the root.
issuer := chains[0][1]
// Now that we know this certificate is valid, create a TLS Certificate for our
// credentials
@ -311,26 +360,17 @@ func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter,
return nil, err
}
// Load the Certificates as server credentials
serverTLSCreds, err := rootCA.NewServerTLSCredentials(&keyPair)
if err != nil {
return nil, err
secConfig, err := NewSecurityConfig(&rootCA, krw, &keyPair, &IssuerInfo{
Subject: issuer.RawSubject,
PublicKey: issuer.RawSubjectPublicKeyInfo,
})
if err == nil {
log.G(ctx).WithFields(logrus.Fields{
"node.id": secConfig.ClientTLSCreds.NodeID(),
"node.role": secConfig.ClientTLSCreds.Role(),
}).Debug("loaded node credentials")
}
// Load the Certificates also as client credentials.
// Both workers and managers always connect to remote managers,
// so ServerName is always set to ManagerRole here.
clientTLSCreds, err := rootCA.NewClientTLSCredentials(&keyPair, ManagerRole)
if err != nil {
return nil, err
}
log.G(ctx).WithFields(logrus.Fields{
"node.id": clientTLSCreds.NodeID(),
"node.role": clientTLSCreds.Role(),
}).Debug("loaded node credentials")
return NewSecurityConfig(&rootCA, krw, clientTLSCreds, serverTLSCreds), nil
return secConfig, err
}
// CertificateRequestConfig contains the information needed to request a
@ -365,12 +405,12 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite
org := identity.NewID()
proposedRole := ManagerRole
tlsKeyPair, err := rootCA.IssueAndSaveNewCertificates(krw, cn, proposedRole, org)
tlsKeyPair, issuerInfo, err := rootCA.IssueAndSaveNewCertificates(krw, cn, proposedRole, org)
switch errors.Cause(err) {
case ErrNoValidSigner:
// Request certificate issuance from a remote CA.
// Last argument is nil because at this point we don't have any valid TLS creds
tlsKeyPair, err = rootCA.RequestAndSaveNewCertificates(ctx, krw, config)
tlsKeyPair, issuerInfo, err = rootCA.RequestAndSaveNewCertificates(ctx, krw, config)
if err != nil {
log.G(ctx).WithError(err).Error("failed to request save new certificate")
return nil, err
@ -388,24 +428,14 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite
return nil, err
}
// Create the Server TLS Credentials for this node. These will not be used by workers.
serverTLSCreds, err := rootCA.NewServerTLSCredentials(tlsKeyPair)
if err != nil {
return nil, err
secConfig, err := NewSecurityConfig(&rootCA, krw, tlsKeyPair, issuerInfo)
if err == nil {
log.G(ctx).WithFields(logrus.Fields{
"node.id": secConfig.ClientTLSCreds.NodeID(),
"node.role": secConfig.ClientTLSCreds.Role(),
}).Debugf("new node credentials generated: %s", krw.Target())
}
// Create a TLSConfig to be used when this node connects as a client to another remote node.
// We're using ManagerRole as remote serverName for TLS host verification
clientTLSCreds, err := rootCA.NewClientTLSCredentials(tlsKeyPair, ManagerRole)
if err != nil {
return nil, err
}
log.G(ctx).WithFields(logrus.Fields{
"node.id": clientTLSCreds.NodeID(),
"node.role": clientTLSCreds.Role(),
}).Debugf("new node credentials generated: %s", krw.Target())
return NewSecurityConfig(&rootCA, krw, clientTLSCreds, serverTLSCreds), nil
return secConfig, err
}
// 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
// Let's request new certs. Renewals don't require a token.
rootCA := s.RootCA()
tlsKeyPair, err := rootCA.RequestAndSaveNewCertificates(ctx,
tlsKeyPair, issuerInfo, err := rootCA.RequestAndSaveNewCertificates(ctx,
s.KeyWriter(),
CertificateRequestConfig{
ConnBroker: connBroker,
@ -432,9 +462,10 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne
log.WithError(err).Errorf("failed to renew the certificate")
return err
}
s.mu.Lock()
defer s.mu.Unlock()
return s.updateTLSCredentials([]tls.Certificate{*tlsKeyPair})
return s.updateTLSCredentials(tlsKeyPair, issuerInfo)
}
// RenewTLSConfig will continuously monitor for the necessity of renewing the local certificates, either by

View file

@ -60,6 +60,9 @@ type Server struct {
lastSeenClusterRootCA *api.RootCA
lastSeenExternalCAs []*api.ExternalCA
secConfigMu sync.Mutex
// before we update the security config with the new root CA, we need to be able to save the root certs
rootPaths CertPaths
}
// DefaultCAConfig returns the default CA Config, with a default expiration.
@ -70,13 +73,14 @@ func DefaultCAConfig() api.CAConfig {
}
// NewServer creates a CA API server.
func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig) *Server {
func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig, rootCAPaths CertPaths) *Server {
return &Server{
store: store,
securityConfig: securityConfig,
pending: make(map[string]*api.Node),
started: make(chan struct{}),
reconciliationRetryInterval: defaultReconciliationRetryInterval,
rootPaths: rootCAPaths,
}
}
@ -582,6 +586,9 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
if err != nil {
return errors.Wrap(err, "invalid Root CA object in cluster")
}
if err := SaveRootCA(updatedRootCA, s.rootPaths); err != nil {
return errors.Wrap(err, "unable to save new root CA certificates")
}
externalCARootPool := updatedRootCA.Pool
if rCA.RootRotation != nil {
@ -609,6 +616,7 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
// we're rotating to a new root, so we only want external CAs with the new root cert
wantedExternalCACert = rCA.RootRotation.CACert
}
wantedExternalCACert = NormalizePEMs(wantedExternalCACert)
// Update our security config with the list of External CA URLs
// from the new cluster state.
@ -623,6 +631,7 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
if len(certForExtCA) == 0 {
certForExtCA = rCA.CACert
}
certForExtCA = NormalizePEMs(certForExtCA)
if extCA.Protocol != api.ExternalCA_CAProtocolCFSSL {
logger.Debugf("skipping external CA %d (url: %s) due to unknown protocol type", i, extCA.URL)
continue

View file

@ -24,28 +24,28 @@ var minRootExpiration = 1 * helpers.OneYear
// determines whether an api.RootCA, api.RootRotation, or api.CAConfig has a signing key (local signer)
func hasSigningKey(a interface{}) bool {
switch b := a.(type) {
case api.RootCA:
case *api.RootCA:
return len(b.CAKey) > 0
case *api.RootRotation:
return b != nil && len(b.CAKey) > 0
case api.CAConfig:
case *api.CAConfig:
return len(b.SigningCACert) > 0 && len(b.SigningCAKey) > 0
default:
panic("needsExternalCAs should be called something of type api.RootCA, *api.RootRotation, or api.CAConfig")
panic("needsExternalCAs should be called something of type *api.RootCA, *api.RootRotation, or *api.CAConfig")
}
}
// Creates a cross-signed intermediate and new api.RootRotation object.
// This function assumes that the root cert and key and the external CAs have already been validated.
func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfig, cluster *api.Cluster, newRootCA ca.RootCA, version uint64) (*api.RootCA, error) {
func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfig, apiRootCA *api.RootCA, newCARootCA ca.RootCA, extCAs []*api.ExternalCA, version uint64) (*api.RootCA, error) {
var (
rootCert, rootKey, crossSignedCert []byte
newRootHasSigner bool
err error
)
rootCert = newRootCA.Certs
if s, err := newRootCA.Signer(); err == nil {
rootCert = newCARootCA.Certs
if s, err := newCARootCA.Signer(); err == nil {
rootCert, rootKey = s.Cert, s.Key
newRootHasSigner = true
}
@ -53,9 +53,9 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
// we have to sign with the original signer, not whatever is in the SecurityConfig's RootCA (which may have an intermediate signer, if
// a root rotation is already in progress)
switch {
case hasSigningKey(cluster.RootCA):
case hasSigningKey(apiRootCA):
var oldRootCA ca.RootCA
oldRootCA, err = ca.NewRootCA(cluster.RootCA.CACert, cluster.RootCA.CACert, cluster.RootCA.CAKey, ca.DefaultNodeCertExpiration, nil)
oldRootCA, err = ca.NewRootCA(apiRootCA.CACert, apiRootCA.CACert, apiRootCA.CAKey, ca.DefaultNodeCertExpiration, nil)
if err == nil {
crossSignedCert, err = oldRootCA.CrossSignCACertificate(rootCert)
}
@ -65,8 +65,8 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
// We need the same credentials but to connect to the original URLs (in case we are in the middle of a root rotation already)
externalCA := securityConfig.ExternalCA().Copy()
var urls []string
for _, c := range cluster.Spec.CAConfig.ExternalCAs {
if c.Protocol == api.ExternalCA_CAProtocolCFSSL && bytes.Equal(c.CACert, cluster.RootCA.CACert) {
for _, c := range extCAs {
if c.Protocol == api.ExternalCA_CAProtocolCFSSL {
urls = append(urls, c.URL)
}
}
@ -75,7 +75,7 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
"must provide an external CA for the current external root CA to generate a cross-signed certificate")
}
externalCA.UpdateURLs(urls...)
crossSignedCert, err = externalCA.CrossSignRootCA(ctx, newRootCA)
crossSignedCert, err = externalCA.CrossSignRootCA(ctx, newCARootCA)
}
if err != nil {
@ -83,11 +83,11 @@ func newRootRotationObject(ctx context.Context, securityConfig *ca.SecurityConfi
return nil, grpc.Errorf(codes.Internal, "unable to generate a cross-signed certificate for root rotation")
}
copied := cluster.RootCA.Copy()
copied := apiRootCA.Copy()
copied.RootRotation = &api.RootRotation{
CACert: rootCert,
CAKey: rootKey,
CrossSignedCACert: crossSignedCert,
CrossSignedCACert: ca.NormalizePEMs(crossSignedCert),
}
copied.LastForcedRotation = version
return copied, nil
@ -120,58 +120,46 @@ func validateExternalCAURL(dialer *net.Dialer, tlsOpts *tls.Config, caURL string
return err
}
// Iterates over all the external CAs, and validates that there is at least 1 reachable, valid external CA for the
// given CA certificate. Returns true if there is, false otherwise.
func hasAtLeastOneExternalCA(ctx context.Context, externalCAs []*api.ExternalCA, securityConfig *ca.SecurityConfig, wantedCert []byte) bool {
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(wantedCert)
dialer := net.Dialer{Timeout: 5 * time.Second}
opts := tls.Config{
RootCAs: pool,
Certificates: securityConfig.ClientTLSCreds.Config().Certificates,
}
for i, ca := range externalCAs {
if ca.Protocol == api.ExternalCA_CAProtocolCFSSL && bytes.Equal(wantedCert, ca.CACert) {
err := validateExternalCAURL(&dialer, &opts, ca.URL)
if err == nil {
return true
// Validates that there is at least 1 reachable, valid external CA for the given CA certificate. Returns true if there is, false otherwise.
// Requires that the wanted cert is already normalized.
func validateHasAtLeastOneExternalCA(ctx context.Context, externalCAs map[string][]*api.ExternalCA, securityConfig *ca.SecurityConfig,
wantedCert []byte, desc string) ([]*api.ExternalCA, error) {
specific, ok := externalCAs[string(wantedCert)]
if ok {
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(wantedCert)
dialer := net.Dialer{Timeout: 5 * time.Second}
opts := tls.Config{
RootCAs: pool,
Certificates: securityConfig.ClientTLSCreds.Config().Certificates,
}
for i, ca := range specific {
if ca.Protocol == api.ExternalCA_CAProtocolCFSSL {
if err := validateExternalCAURL(&dialer, &opts, ca.URL); err != nil {
log.G(ctx).WithError(err).Warnf("external CA # %d is unreachable or invalid", i+1)
} else {
return specific, nil
}
}
log.G(ctx).WithError(err).Warnf("external CA # %d is unreachable or invalid", i+1)
}
}
return false
return nil, grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the %s CA certificate", desc)
}
// All new external CA definitions must include the CA cert associated with the external CA.
// If the current root CA requires an external CA, then at least one, reachable valid external CA must be provided that
// corresponds with the current RootCA's certificate.
//
// Similarly for the desired CA certificate, if one is specified. Similarly for the current outstanding root CA rotation,
// if one is specified and will not be replaced with the desired CA.
func validateHasRequiredExternalCAs(ctx context.Context, securityConfig *ca.SecurityConfig, cluster *api.Cluster) error {
config := cluster.Spec.CAConfig
for _, ca := range config.ExternalCAs {
if len(ca.CACert) == 0 {
return grpc.Errorf(codes.InvalidArgument, "must specify CA certificate for each external CA")
// validates that the list of external CAs have valid certs associated with them, and produce a mapping of subject/pubkey:external
// for later validation of required external CAs
func getNormalizedExtCAs(caConfig *api.CAConfig) (map[string][]*api.ExternalCA, error) {
extCAs := make(map[string][]*api.ExternalCA)
for _, extCA := range caConfig.ExternalCAs {
if len(extCA.CACert) == 0 {
return nil, grpc.Errorf(codes.InvalidArgument, "must specify CA certificate for each external CA")
}
certKey := string(ca.NormalizePEMs(extCA.CACert))
extCAs[certKey] = append(extCAs[certKey], extCA)
}
if !hasSigningKey(cluster.RootCA) && !hasAtLeastOneExternalCA(ctx, config.ExternalCAs, securityConfig, cluster.RootCA.CACert) {
return grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the current CA certificate")
}
if len(config.SigningCACert) > 0 { // a signing cert is specified
if !hasSigningKey(config) && !hasAtLeastOneExternalCA(ctx, config.ExternalCAs, securityConfig, config.SigningCACert) {
return grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the desired CA certificate")
}
} else if config.ForceRotate == cluster.RootCA.LastForcedRotation && cluster.RootCA.RootRotation != nil {
// 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
if !hasSigningKey(cluster.RootCA.RootRotation) && !hasAtLeastOneExternalCA(ctx, config.ExternalCAs, securityConfig, cluster.RootCA.RootRotation.CACert) {
return grpc.Errorf(codes.InvalidArgument, "there must be at least one valid, reachable external CA corresponding to the next CA certificate")
}
}
return nil
return extCAs, nil
}
// 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
// - Otherwise, start a new root rotation using the desired signing cert and desired signing key as the root rotation
// signing cert and key. If a root rotation is already in progress, just replace it and start over.
func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cluster *api.Cluster) (*api.RootCA, error) {
newConfig := cluster.Spec.CAConfig
newConfig := cluster.Spec.CAConfig.Copy()
newConfig.SigningCACert = ca.NormalizePEMs(newConfig.SigningCACert) // ensure this is normalized before we use it
if len(newConfig.SigningCAKey) > 0 && len(newConfig.SigningCACert) == 0 {
return nil, grpc.Errorf(codes.InvalidArgument, "if a signing CA key is provided, the signing CA cert must also be provided")
}
if err := validateHasRequiredExternalCAs(ctx, securityConfig, cluster); err != nil {
extCAs, err := getNormalizedExtCAs(newConfig) // validate that the list of external CAs is not malformed
if err != nil {
return nil, err
}
normalizedRootCA := ca.NormalizePEMs(cluster.RootCA.CACert)
var oldCertExtCAs []*api.ExternalCA
if !hasSigningKey(&cluster.RootCA) {
oldCertExtCAs, err = validateHasAtLeastOneExternalCA(ctx, extCAs, securityConfig, normalizedRootCA, "current")
if err != nil {
return nil, err
}
}
// if the desired CA cert and key are not set, then we are happy with the current root CA configuration, unless
// the ForceRotate version has changed
if len(newConfig.SigningCACert) == 0 {
@ -214,8 +213,18 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
if err != nil {
return nil, grpc.Errorf(codes.Internal, err.Error())
}
return newRootRotationObject(ctx, securityConfig, cluster, newRootCA, newConfig.ForceRotate)
return newRootRotationObject(ctx, securityConfig, &cluster.RootCA, newRootCA, oldCertExtCAs, newConfig.ForceRotate)
}
// we also need to make sure that if the current root rotation requires an external CA, those external CAs are
// still valid
if cluster.RootCA.RootRotation != nil && !hasSigningKey(cluster.RootCA.RootRotation) {
_, err := validateHasAtLeastOneExternalCA(ctx, extCAs, securityConfig, ca.NormalizePEMs(cluster.RootCA.RootRotation.CACert), "next")
if err != nil {
return nil, err
}
}
return &cluster.RootCA, nil // no change, return as is
}
@ -243,8 +252,14 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
return nil, grpc.Errorf(codes.InvalidArgument, "CA certificate expires too soon")
}
if !hasSigningKey(newConfig) {
if _, err := validateHasAtLeastOneExternalCA(ctx, extCAs, securityConfig, newConfig.SigningCACert, "desired"); err != nil {
return nil, err
}
}
// check if we can abort any existing root rotations
if bytes.Equal(cluster.RootCA.CACert, cluster.Spec.CAConfig.SigningCACert) {
if bytes.Equal(normalizedRootCA, newConfig.SigningCACert) {
copied := cluster.RootCA.Copy()
copied.CAKey = newConfig.SigningCAKey
copied.RootRotation = nil
@ -253,7 +268,7 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
}
// check if this is the same desired cert as an existing root rotation
if r := cluster.RootCA.RootRotation; r != nil && bytes.Equal(r.CACert, cluster.Spec.CAConfig.SigningCACert) {
if r := cluster.RootCA.RootRotation; r != nil && bytes.Equal(ca.NormalizePEMs(r.CACert), newConfig.SigningCACert) {
copied := cluster.RootCA.Copy()
copied.RootRotation.CAKey = newConfig.SigningCAKey
copied.LastForcedRotation = newConfig.ForceRotate
@ -261,5 +276,5 @@ func validateCAConfig(ctx context.Context, securityConfig *ca.SecurityConfig, cl
}
// ok, everything's different; we have to begin a new root rotation which means generating a new cross-signed cert
return newRootRotationObject(ctx, securityConfig, cluster, newRootCA, newConfig.ForceRotate)
return newRootRotationObject(ctx, securityConfig, &cluster.RootCA, newRootCA, oldCertExtCAs, newConfig.ForceRotate)
}

View file

@ -38,7 +38,7 @@ func validateClusterSpec(spec *api.ClusterSpec) error {
}
// Validate that AcceptancePolicies only include Secrets that are bcrypted
// TODO(diogo): Add a global list of acceptace algorithms. We only support bcrypt for now.
// TODO(diogo): Add a global list of acceptance algorithms. We only support bcrypt for now.
if len(spec.AcceptancePolicy.Policies) > 0 {
for _, policy := range spec.AcceptancePolicy.Policies {
if policy.Secret != nil && strings.ToLower(policy.Secret.Alg) != "bcrypt" {

View file

@ -13,7 +13,10 @@ import (
"google.golang.org/grpc/codes"
)
var isValidName = regexp.MustCompile(`^[a-zA-Z0-9](?:[-_]*[A-Za-z0-9]+)*$`)
var isValidDNSName = regexp.MustCompile(`^[a-zA-Z0-9](?:[-_]*[A-Za-z0-9]+)*$`)
// configs and secrets have different naming requirements from tasks and services
var isValidConfigOrSecretName = regexp.MustCompile(`^[a-zA-Z0-9]+(?:[a-zA-Z0-9-_.]*[a-zA-Z0-9])?$`)
func buildFilters(by func(string) store.By, values []string) store.By {
filters := make([]store.By, 0, len(values))
@ -68,7 +71,7 @@ func validateAnnotations(m api.Annotations) error {
if m.Name == "" {
return grpc.Errorf(codes.InvalidArgument, "meta: name must be provided")
}
if !isValidName.MatchString(m.Name) {
if !isValidDNSName.MatchString(m.Name) {
// if the name doesn't match the regex
return grpc.Errorf(codes.InvalidArgument, "name must be valid as a DNS name component")
}
@ -79,6 +82,17 @@ func validateAnnotations(m api.Annotations) error {
return nil
}
func validateConfigOrSecretAnnotations(m api.Annotations) error {
if m.Name == "" {
return grpc.Errorf(codes.InvalidArgument, "name must be provided")
} else if len(m.Name) > 64 || !isValidConfigOrSecretName.MatchString(m.Name) {
// if the name doesn't match the regex
return grpc.Errorf(codes.InvalidArgument,
"invalid name, only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]")
}
return nil
}
func validateDriver(driver *api.Driver, pg plugingetter.PluginGetter, pluginType string) error {
if driver == nil {
// It is ok to not specify the driver. We will choose

View file

@ -0,0 +1,248 @@
package controlapi
import (
"bytes"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/identity"
"github.com/docker/swarmkit/log"
"github.com/docker/swarmkit/manager/state/store"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
// MaxConfigSize is the maximum byte length of the `Config.Spec.Data` field.
const MaxConfigSize = 500 * 1024 // 500KB
// assumes spec is not nil
func configFromConfigSpec(spec *api.ConfigSpec) *api.Config {
return &api.Config{
ID: identity.NewID(),
Spec: *spec,
}
}
// GetConfig returns a `GetConfigResponse` with a `Config` with the same
// id as `GetConfigRequest.ConfigID`
// - Returns `NotFound` if the Config with the given id is not found.
// - Returns `InvalidArgument` if the `GetConfigRequest.ConfigID` is empty.
// - Returns an error if getting fails.
func (s *Server) GetConfig(ctx context.Context, request *api.GetConfigRequest) (*api.GetConfigResponse, error) {
if request.ConfigID == "" {
return nil, grpc.Errorf(codes.InvalidArgument, "config ID must be provided")
}
var config *api.Config
s.store.View(func(tx store.ReadTx) {
config = store.GetConfig(tx, request.ConfigID)
})
if config == nil {
return nil, grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
}
return &api.GetConfigResponse{Config: config}, nil
}
// UpdateConfig updates a Config referenced by ConfigID with the given ConfigSpec.
// - Returns `NotFound` if the Config is not found.
// - Returns `InvalidArgument` if the ConfigSpec is malformed or anything other than Labels is changed
// - Returns an error if the update fails.
func (s *Server) UpdateConfig(ctx context.Context, request *api.UpdateConfigRequest) (*api.UpdateConfigResponse, error) {
if request.ConfigID == "" || request.ConfigVersion == nil {
return nil, grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
}
var config *api.Config
err := s.store.Update(func(tx store.Tx) error {
config = store.GetConfig(tx, request.ConfigID)
if config == nil {
return grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
}
// Check if the Name is different than the current name, or the config is non-nil and different
// than the current config
if config.Spec.Annotations.Name != request.Spec.Annotations.Name ||
(request.Spec.Data != nil && !bytes.Equal(request.Spec.Data, config.Spec.Data)) {
return grpc.Errorf(codes.InvalidArgument, "only updates to Labels are allowed")
}
// We only allow updating Labels
config.Meta.Version = *request.ConfigVersion
config.Spec.Annotations.Labels = request.Spec.Annotations.Labels
return store.UpdateConfig(tx, config)
})
if err != nil {
return nil, err
}
log.G(ctx).WithFields(logrus.Fields{
"config.ID": request.ConfigID,
"config.Name": request.Spec.Annotations.Name,
"method": "UpdateConfig",
}).Debugf("config updated")
return &api.UpdateConfigResponse{
Config: config,
}, nil
}
// ListConfigs returns a `ListConfigResponse` with a list all non-internal `Config`s being
// managed, or all configs matching any name in `ListConfigsRequest.Names`, any
// name prefix in `ListConfigsRequest.NamePrefixes`, any id in
// `ListConfigsRequest.ConfigIDs`, or any id prefix in `ListConfigsRequest.IDPrefixes`.
// - Returns an error if listing fails.
func (s *Server) ListConfigs(ctx context.Context, request *api.ListConfigsRequest) (*api.ListConfigsResponse, error) {
var (
configs []*api.Config
respConfigs []*api.Config
err error
byFilters []store.By
by store.By
labels map[string]string
)
// return all configs that match either any of the names or any of the name prefixes (why would you give both?)
if request.Filters != nil {
for _, name := range request.Filters.Names {
byFilters = append(byFilters, store.ByName(name))
}
for _, prefix := range request.Filters.NamePrefixes {
byFilters = append(byFilters, store.ByNamePrefix(prefix))
}
for _, prefix := range request.Filters.IDPrefixes {
byFilters = append(byFilters, store.ByIDPrefix(prefix))
}
labels = request.Filters.Labels
}
switch len(byFilters) {
case 0:
by = store.All
case 1:
by = byFilters[0]
default:
by = store.Or(byFilters...)
}
s.store.View(func(tx store.ReadTx) {
configs, err = store.FindConfigs(tx, by)
})
if err != nil {
return nil, err
}
// filter by label
for _, config := range configs {
if !filterMatchLabels(config.Spec.Annotations.Labels, labels) {
continue
}
respConfigs = append(respConfigs, config)
}
return &api.ListConfigsResponse{Configs: respConfigs}, nil
}
// CreateConfig creates and returns a `CreateConfigResponse` with a `Config` based
// on the provided `CreateConfigRequest.ConfigSpec`.
// - Returns `InvalidArgument` if the `CreateConfigRequest.ConfigSpec` is malformed,
// or if the config data is too long or contains invalid characters.
// - Returns an error if the creation fails.
func (s *Server) CreateConfig(ctx context.Context, request *api.CreateConfigRequest) (*api.CreateConfigResponse, error) {
if err := validateConfigSpec(request.Spec); err != nil {
return nil, err
}
config := configFromConfigSpec(request.Spec) // the store will handle name conflicts
err := s.store.Update(func(tx store.Tx) error {
return store.CreateConfig(tx, config)
})
switch err {
case store.ErrNameConflict:
return nil, grpc.Errorf(codes.AlreadyExists, "config %s already exists", request.Spec.Annotations.Name)
case nil:
log.G(ctx).WithFields(logrus.Fields{
"config.Name": request.Spec.Annotations.Name,
"method": "CreateConfig",
}).Debugf("config created")
return &api.CreateConfigResponse{Config: config}, nil
default:
return nil, err
}
}
// RemoveConfig removes the config referenced by `RemoveConfigRequest.ID`.
// - Returns `InvalidArgument` if `RemoveConfigRequest.ID` is empty.
// - Returns `NotFound` if the a config named `RemoveConfigRequest.ID` is not found.
// - Returns `ConfigInUse` if the config is currently in use
// - Returns an error if the deletion fails.
func (s *Server) RemoveConfig(ctx context.Context, request *api.RemoveConfigRequest) (*api.RemoveConfigResponse, error) {
if request.ConfigID == "" {
return nil, grpc.Errorf(codes.InvalidArgument, "config ID must be provided")
}
err := s.store.Update(func(tx store.Tx) error {
// Check if the config exists
config := store.GetConfig(tx, request.ConfigID)
if config == nil {
return grpc.Errorf(codes.NotFound, "could not find config %s", request.ConfigID)
}
// Check if any services currently reference this config, return error if so
services, err := store.FindServices(tx, store.ByReferencedConfigID(request.ConfigID))
if err != nil {
return grpc.Errorf(codes.Internal, "could not find services using config %s: %v", request.ConfigID, err)
}
if len(services) != 0 {
serviceNames := make([]string, 0, len(services))
for _, service := range services {
serviceNames = append(serviceNames, service.Spec.Annotations.Name)
}
configName := config.Spec.Annotations.Name
serviceNameStr := strings.Join(serviceNames, ", ")
serviceStr := "services"
if len(serviceNames) == 1 {
serviceStr = "service"
}
return grpc.Errorf(codes.InvalidArgument, "config '%s' is in use by the following %s: %v", configName, serviceStr, serviceNameStr)
}
return store.DeleteConfig(tx, request.ConfigID)
})
switch err {
case store.ErrNotExist:
return nil, grpc.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
case nil:
log.G(ctx).WithFields(logrus.Fields{
"config.ID": request.ConfigID,
"method": "RemoveConfig",
}).Debugf("config removed")
return &api.RemoveConfigResponse{}, nil
default:
return nil, err
}
}
func validateConfigSpec(spec *api.ConfigSpec) error {
if spec == nil {
return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
}
if err := validateConfigOrSecretAnnotations(spec.Annotations); err != nil {
return err
}
if len(spec.Data) >= MaxConfigSize || len(spec.Data) < 1 {
return grpc.Errorf(codes.InvalidArgument, "config data must be larger than 0 and less than %d bytes", MaxConfigSize)
}
return nil
}

View file

@ -2,7 +2,6 @@ package controlapi
import (
"crypto/subtle"
"regexp"
"strings"
"github.com/Sirupsen/logrus"
@ -15,13 +14,9 @@ import (
"google.golang.org/grpc/codes"
)
// Currently this is contains the unimplemented secret functions in order to satisfy the interface
// MaxSecretSize is the maximum byte length of the `Secret.Spec.Data` field.
const MaxSecretSize = 500 * 1024 // 500KB
var validSecretNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9]+(?:[a-zA-Z0-9-_.]*[a-zA-Z0-9])?$`)
// assumes spec is not nil
func secretFromSecretSpec(spec *api.SecretSpec) *api.Secret {
return &api.Secret{
@ -247,7 +242,7 @@ func validateSecretSpec(spec *api.SecretSpec) error {
if spec == nil {
return grpc.Errorf(codes.InvalidArgument, errInvalidArgument.Error())
}
if err := validateSecretAnnotations(spec.Annotations); err != nil {
if err := validateConfigOrSecretAnnotations(spec.Annotations); err != nil {
return err
}
@ -256,14 +251,3 @@ func validateSecretSpec(spec *api.SecretSpec) error {
}
return nil
}
func validateSecretAnnotations(m api.Annotations) error {
if m.Name == "" {
return grpc.Errorf(codes.InvalidArgument, "name must be provided")
} else if len(m.Name) > 64 || !validSecretNameRegexp.MatchString(m.Name) {
// if the name doesn't match the regex
return grpc.Errorf(codes.InvalidArgument,
"invalid name, only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]")
}
return nil
}

View file

@ -206,11 +206,16 @@ func validateTaskSpec(taskSpec api.TaskSpec) error {
return err
}
// Check to see if the Secret Reference portion of the spec is valid
// Check to see if the secret reference portion of the spec is valid
if err := validateSecretRefsSpec(taskSpec); err != nil {
return err
}
// Check to see if the config reference portion of the spec is valid
if err := validateConfigRefsSpec(taskSpec); err != nil {
return err
}
if taskSpec.GetRuntime() == nil {
return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime")
}
@ -314,6 +319,48 @@ func validateSecretRefsSpec(spec api.TaskSpec) error {
return nil
}
// validateConfigRefsSpec finds if the configs passed in spec are valid and have no
// conflicting targets.
func validateConfigRefsSpec(spec api.TaskSpec) error {
container := spec.GetContainer()
if container == nil {
return nil
}
// Keep a map to track all the targets that will be exposed
// The string returned is only used for logging. It could as well be struct{}{}
existingTargets := make(map[string]string)
for _, configRef := range container.Configs {
// ConfigID and ConfigName are mandatory, we have invalid references without them
if configRef.ConfigID == "" || configRef.ConfigName == "" {
return grpc.Errorf(codes.InvalidArgument, "malformed config reference")
}
// Every config reference requires a Target
if configRef.GetTarget() == nil {
return grpc.Errorf(codes.InvalidArgument, "malformed config reference, no target provided")
}
// If this is a file target, we will ensure filename uniqueness
if configRef.GetFile() != nil {
fileName := configRef.GetFile().Name
// Validate the file name
if fileName == "" {
return grpc.Errorf(codes.InvalidArgument, "malformed file config reference, invalid target file name provided")
}
// If this target is already in use, we have conflicting targets
if prevConfigName, ok := existingTargets[fileName]; ok {
return grpc.Errorf(codes.InvalidArgument, "config references '%s' and '%s' have a conflicting target: '%s'", prevConfigName, configRef.ConfigName, fileName)
}
existingTargets[fileName] = configRef.ConfigName
}
}
return nil
}
func (s *Server) validateNetworks(networks []*api.NetworkAttachmentConfig) error {
for _, na := range networks {
var network *api.Network
@ -459,6 +506,35 @@ func (s *Server) checkSecretExistence(tx store.Tx, spec *api.ServiceSpec) error
return nil
}
// checkConfigExistence finds if the config exists
func (s *Server) checkConfigExistence(tx store.Tx, spec *api.ServiceSpec) error {
container := spec.Task.GetContainer()
if container == nil {
return nil
}
var failedConfigs []string
for _, configRef := range container.Configs {
config := store.GetConfig(tx, configRef.ConfigID)
// Check to see if the config exists and configRef.ConfigName matches the actual configName
if config == nil || config.Spec.Annotations.Name != configRef.ConfigName {
failedConfigs = append(failedConfigs, configRef.ConfigName)
}
}
if len(failedConfigs) > 0 {
configStr := "configs"
if len(failedConfigs) == 1 {
configStr = "config"
}
return grpc.Errorf(codes.InvalidArgument, "%s not found: %v", configStr, strings.Join(failedConfigs, ", "))
}
return nil
}
// CreateService creates and returns a Service based on the provided ServiceSpec.
// - Returns `InvalidArgument` if the ServiceSpec is malformed.
// - Returns `Unimplemented` if the ServiceSpec references unimplemented features.
@ -498,6 +574,10 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe
if err != nil {
return err
}
err = s.checkConfigExistence(tx, request.Spec)
if err != nil {
return err
}
return store.CreateService(tx, service)
})
@ -585,6 +665,11 @@ func (s *Server) UpdateService(ctx context.Context, request *api.UpdateServiceRe
return err
}
err = s.checkConfigExistence(tx, request.Spec)
if err != nil {
return err
}
// orchestrator is designed to be stateless, so it should not deal
// with service mode change (comparing current config with previous config).
// 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
service.Spec = *request.Spec.Copy()
// Set spec version. Note that this will not match the
// service's Meta.Version after the store update. The
// versionsfor the spec and the service itself are not
// versions for the spec and the service itself are not
// meant to be directly comparable.
service.SpecVersion = service.Meta.Version.Copy()

View file

@ -0,0 +1,247 @@
package dispatcher
import (
"github.com/Sirupsen/logrus"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/equality"
"github.com/docker/swarmkit/manager/state/store"
)
// Used as a key in tasksUsingDependency and changes. Only using the
// ID could cause (rare) collisions between different types of
// objects, so we also include the type of object in the key.
type objectType int
const (
typeTask objectType = iota
typeSecret
typeConfig
)
type typeAndID struct {
id string
objType objectType
}
type assignmentSet struct {
tasksMap map[string]*api.Task
tasksUsingDependency map[typeAndID]map[string]struct{}
changes map[typeAndID]*api.AssignmentChange
log *logrus.Entry
}
func newAssignmentSet(log *logrus.Entry) *assignmentSet {
return &assignmentSet{
changes: make(map[typeAndID]*api.AssignmentChange),
tasksMap: make(map[string]*api.Task),
tasksUsingDependency: make(map[typeAndID]map[string]struct{}),
log: log,
}
}
func (a *assignmentSet) addTaskDependencies(readTx store.ReadTx, t *api.Task) {
var secrets []*api.SecretReference
container := t.Spec.GetContainer()
if container != nil {
secrets = container.Secrets
}
for _, secretRef := range secrets {
secretID := secretRef.SecretID
mapKey := typeAndID{objType: typeSecret, id: secretID}
if len(a.tasksUsingDependency[mapKey]) == 0 {
a.tasksUsingDependency[mapKey] = make(map[string]struct{})
secret := store.GetSecret(readTx, secretID)
if secret == nil {
a.log.WithFields(logrus.Fields{
"secret.id": secretID,
"secret.name": secretRef.SecretName,
}).Debug("secret not found")
continue
}
// If the secret was found, add this secret to
// our set that we send down.
a.changes[mapKey] = &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Secret{
Secret: secret,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
}
a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
}
var configs []*api.ConfigReference
if container != nil {
configs = container.Configs
}
for _, configRef := range configs {
configID := configRef.ConfigID
mapKey := typeAndID{objType: typeConfig, id: configID}
if len(a.tasksUsingDependency[mapKey]) == 0 {
a.tasksUsingDependency[mapKey] = make(map[string]struct{})
config := store.GetConfig(readTx, configID)
if config == nil {
a.log.WithFields(logrus.Fields{
"config.id": configID,
"config.name": configRef.ConfigName,
}).Debug("config not found")
continue
}
// If the config was found, add this config to
// our set that we send down.
a.changes[mapKey] = &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Config{
Config: config,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
}
a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
}
}
func (a *assignmentSet) releaseDependency(mapKey typeAndID, assignment *api.Assignment, taskID string) bool {
delete(a.tasksUsingDependency[mapKey], taskID)
if len(a.tasksUsingDependency[mapKey]) != 0 {
return false
}
// No tasks are using the dependency anymore
delete(a.tasksUsingDependency, mapKey)
a.changes[mapKey] = &api.AssignmentChange{
Assignment: assignment,
Action: api.AssignmentChange_AssignmentActionRemove,
}
return true
}
func (a *assignmentSet) releaseTaskDependencies(t *api.Task) bool {
var modified bool
container := t.Spec.GetContainer()
var secrets []*api.SecretReference
if container != nil {
secrets = container.Secrets
}
for _, secretRef := range secrets {
secretID := secretRef.SecretID
mapKey := typeAndID{objType: typeSecret, id: secretID}
assignment := &api.Assignment{
Item: &api.Assignment_Secret{
Secret: &api.Secret{ID: secretID},
},
}
if a.releaseDependency(mapKey, assignment, t.ID) {
modified = true
}
}
var configs []*api.ConfigReference
if container != nil {
configs = container.Configs
}
for _, configRef := range configs {
configID := configRef.ConfigID
mapKey := typeAndID{objType: typeConfig, id: configID}
assignment := &api.Assignment{
Item: &api.Assignment_Config{
Config: &api.Config{ID: configID},
},
}
if a.releaseDependency(mapKey, assignment, t.ID) {
modified = true
}
}
return modified
}
func (a *assignmentSet) addOrUpdateTask(readTx store.ReadTx, t *api.Task) bool {
// We only care about tasks that are ASSIGNED or higher.
if t.Status.State < api.TaskStateAssigned {
return false
}
if oldTask, exists := a.tasksMap[t.ID]; exists {
// States ASSIGNED and below are set by the orchestrator/scheduler,
// not the agent, so tasks in these states need to be sent to the
// agent even if nothing else has changed.
if equality.TasksEqualStable(oldTask, t) && t.Status.State > api.TaskStateAssigned {
// this update should not trigger a task change for the agent
a.tasksMap[t.ID] = t
// If this task got updated to a final state, let's release
// the dependencies that are being used by the task
if t.Status.State > api.TaskStateRunning {
// If releasing the dependencies caused us to
// remove something from the assignment set,
// mark one modification.
return a.releaseTaskDependencies(t)
}
return false
}
} else if t.Status.State <= api.TaskStateRunning {
// If this task wasn't part of the assignment set before, and it's <= RUNNING
// add the dependencies it references to the assignment.
// Task states > RUNNING are worker reported only, are never created in
// a > RUNNING state.
a.addTaskDependencies(readTx, t)
}
a.tasksMap[t.ID] = t
a.changes[typeAndID{objType: typeTask, id: t.ID}] = &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Task{
Task: t,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
return true
}
func (a *assignmentSet) removeTask(t *api.Task) bool {
if _, exists := a.tasksMap[t.ID]; !exists {
return false
}
a.changes[typeAndID{objType: typeTask, id: t.ID}] = &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Task{
Task: &api.Task{ID: t.ID},
},
},
Action: api.AssignmentChange_AssignmentActionRemove,
}
delete(a.tasksMap, t.ID)
// Release the dependencies being used by this task.
// Ignoring the return here. We will always mark this as a
// modification, since a task is being removed.
a.releaseTaskDependencies(t)
return true
}
func (a *assignmentSet) message() api.AssignmentsMessage {
var message api.AssignmentsMessage
for _, change := range a.changes {
message.Changes = append(message.Changes, change)
}
// The the set of changes is reinitialized to prepare for formation
// of the next message.
a.changes = make(map[typeAndID]*api.AssignmentChange)
return message
}

View file

@ -102,20 +102,29 @@ type nodeUpdate struct {
description *api.NodeDescription
}
// clusterUpdate is an object that stores an update to the cluster that should trigger
// a new session message. These are pointers to indicate the difference between
// "there is no update" and "update this to nil"
type clusterUpdate struct {
managerUpdate *[]*api.WeightedPeer
bootstrapKeyUpdate *[]*api.EncryptionKey
rootCAUpdate *[]byte
}
// Dispatcher is responsible for dispatching tasks and tracking agent health.
type Dispatcher struct {
mu sync.Mutex
wg sync.WaitGroup
nodes *nodeStore
store *store.MemoryStore
mgrQueue *watch.Queue
lastSeenManagers []*api.WeightedPeer
networkBootstrapKeys []*api.EncryptionKey
keyMgrQueue *watch.Queue
lastSeenRootCert []byte
config *Config
cluster Cluster
ctx context.Context
cancel context.CancelFunc
clusterUpdateQueue *watch.Queue
taskUpdates map[string]*api.TaskStatus // indexed by task ID
taskUpdatesLock sync.Mutex
@ -196,6 +205,7 @@ func (d *Dispatcher) Run(ctx context.Context) error {
if clusters[0].NetworkBootstrapKeys != nil {
d.networkBootstrapKeys = clusters[0].NetworkBootstrapKeys
}
d.lastSeenRootCert = clusters[0].RootCA.CACert
}
return nil
},
@ -205,9 +215,8 @@ func (d *Dispatcher) Run(ctx context.Context) error {
d.mu.Unlock()
return err
}
// set queues here to guarantee that Close will close them
d.mgrQueue = watch.NewQueue()
d.keyMgrQueue = watch.NewQueue()
// set queue here to guarantee that Close will close it
d.clusterUpdateQueue = watch.NewQueue()
peerWatcher, peerCancel := d.cluster.SubscribePeers()
defer peerCancel()
@ -231,7 +240,7 @@ func (d *Dispatcher) Run(ctx context.Context) error {
d.mu.Lock()
d.lastSeenManagers = mgrs
d.mu.Unlock()
d.mgrQueue.Publish(mgrs)
d.clusterUpdateQueue.Publish(clusterUpdate{managerUpdate: &mgrs})
}
batchTimer := time.NewTimer(maxBatchInterval)
@ -259,9 +268,13 @@ func (d *Dispatcher) Run(ctx context.Context) error {
d.nodes.updatePeriod(d.config.HeartbeatPeriod, d.config.HeartbeatEpsilon, d.config.GracePeriodMultiplier)
}
}
d.lastSeenRootCert = cluster.Cluster.RootCA.CACert
d.networkBootstrapKeys = cluster.Cluster.NetworkBootstrapKeys
d.mu.Unlock()
d.keyMgrQueue.Publish(cluster.Cluster.NetworkBootstrapKeys)
d.clusterUpdateQueue.Publish(clusterUpdate{
bootstrapKeyUpdate: &cluster.Cluster.NetworkBootstrapKeys,
rootCAUpdate: &cluster.Cluster.RootCA.CACert,
})
case <-ctx.Done():
return nil
}
@ -286,8 +299,7 @@ func (d *Dispatcher) Stop() error {
d.processUpdatesCond.Broadcast()
d.processUpdatesLock.Unlock()
d.mgrQueue.Close()
d.keyMgrQueue.Close()
d.clusterUpdateQueue.Close()
d.wg.Wait()
@ -812,12 +824,10 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
}
var (
sequence int64
appliesTo string
initial api.AssignmentsMessage
sequence int64
appliesTo string
assignments = newAssignmentSet(log)
)
tasksMap := make(map[string]*api.Task)
tasksUsingSecret := make(map[string]map[string]struct{})
sendMessage := func(msg api.AssignmentsMessage, assignmentType api.AssignmentsMessage_Type) error {
sequence++
@ -832,39 +842,6 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
return nil
}
// returns a slice of new secrets to send down
addSecretsForTask := func(readTx store.ReadTx, t *api.Task) []*api.Secret {
container := t.Spec.GetContainer()
if container == nil {
return nil
}
var newSecrets []*api.Secret
for _, secretRef := range container.Secrets {
secretID := secretRef.SecretID
log := log.WithFields(logrus.Fields{
"secret.id": secretID,
"secret.name": secretRef.SecretName,
})
if len(tasksUsingSecret[secretID]) == 0 {
tasksUsingSecret[secretID] = make(map[string]struct{})
secret := store.GetSecret(readTx, secretID)
if secret == nil {
log.Debug("secret not found")
continue
}
// If the secret was found, add this secret to
// our set that we send down.
newSecrets = append(newSecrets, secret)
}
tasksUsingSecret[secretID][t.ID] = struct{}{}
}
return newSecrets
}
// TODO(aaronl): Also send node secrets that should be exposed to
// this node.
nodeTasks, cancel, err := store.ViewAndWatch(
@ -876,57 +853,22 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
}
for _, t := range tasks {
// We only care about tasks that are ASSIGNED or
// higher. If the state is below ASSIGNED, the
// task may not meet the constraints for this
// node, so we have to be careful about sending
// secrets associated with it.
if t.Status.State < api.TaskStateAssigned {
continue
}
tasksMap[t.ID] = t
taskChange := &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Task{
Task: t,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
initial.Changes = append(initial.Changes, taskChange)
// Only send secrets down if these tasks are in < RUNNING
if t.Status.State <= api.TaskStateRunning {
newSecrets := addSecretsForTask(readTx, t)
for _, secret := range newSecrets {
secretChange := &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Secret{
Secret: secret,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
initial.Changes = append(initial.Changes, secretChange)
}
}
assignments.addOrUpdateTask(readTx, t)
}
return nil
},
api.EventUpdateTask{Task: &api.Task{NodeID: nodeID},
Checks: []api.TaskCheckFunc{api.TaskCheckNodeID}},
api.EventDeleteTask{Task: &api.Task{NodeID: nodeID},
Checks: []api.TaskCheckFunc{api.TaskCheckNodeID}},
api.EventUpdateSecret{},
api.EventDeleteSecret{},
)
if err != nil {
return err
}
defer cancel()
if err := sendMessage(initial, api.AssignmentsMessage_COMPLETE); err != nil {
if err := sendMessage(assignments.message(), api.AssignmentsMessage_COMPLETE); err != nil {
return err
}
@ -938,14 +880,9 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
// bursty events should be processed in batches and sent out together
var (
update api.AssignmentsMessage
modificationCnt int
batchingTimer *time.Timer
batchingTimeout <-chan time.Time
updateTasks = make(map[string]*api.Task)
updateSecrets = make(map[string]*api.Secret)
removeTasks = make(map[string]struct{})
removeSecrets = make(map[string]struct{})
)
oneModification := func() {
@ -959,28 +896,6 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
}
}
// Release the secrets references from this task
releaseSecretsForTask := func(t *api.Task) bool {
var modified bool
container := t.Spec.GetContainer()
if container == nil {
return modified
}
for _, secretRef := range container.Secrets {
secretID := secretRef.SecretID
delete(tasksUsingSecret[secretID], t.ID)
if len(tasksUsingSecret[secretID]) == 0 {
// No tasks are using the secret anymore
delete(tasksUsingSecret, secretID)
removeSecrets[secretID] = struct{}{}
modified = true
}
}
return modified
}
// The batching loop waits for 50 ms after the most recent
// change, or until modificationBatchLimit is reached. The
// worst case latency is modificationBatchLimit * batchingWaitTime,
@ -996,78 +911,17 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
// them to ASSIGNED. If this ever changes, we will need
// to monitor task creations as well.
case api.EventUpdateTask:
// We only care about tasks that are ASSIGNED or
// higher.
if v.Task.Status.State < api.TaskStateAssigned {
continue
}
if oldTask, exists := tasksMap[v.Task.ID]; exists {
// States ASSIGNED and below are set by the orchestrator/scheduler,
// not the agent, so tasks in these states need to be sent to the
// agent even if nothing else has changed.
if equality.TasksEqualStable(oldTask, v.Task) && v.Task.Status.State > api.TaskStateAssigned {
// this update should not trigger a task change for the agent
tasksMap[v.Task.ID] = v.Task
// If this task got updated to a final state, let's release
// the secrets that are being used by the task
if v.Task.Status.State > api.TaskStateRunning {
// If releasing the secrets caused a secret to be
// removed from an agent, mark one modification
if releaseSecretsForTask(v.Task) {
oneModification()
}
}
continue
d.store.View(func(readTx store.ReadTx) {
if assignments.addOrUpdateTask(readTx, v.Task) {
oneModification()
}
} else if v.Task.Status.State <= api.TaskStateRunning {
// If this task wasn't part of the assignment set before, and it's <= RUNNING
// add the secrets it references to the secrets assignment.
// Task states > RUNNING are worker reported only, are never created in
// a > RUNNING state.
var newSecrets []*api.Secret
d.store.View(func(readTx store.ReadTx) {
newSecrets = addSecretsForTask(readTx, v.Task)
})
for _, secret := range newSecrets {
updateSecrets[secret.ID] = secret
}
}
tasksMap[v.Task.ID] = v.Task
updateTasks[v.Task.ID] = v.Task
oneModification()
})
case api.EventDeleteTask:
if _, exists := tasksMap[v.Task.ID]; !exists {
continue
if assignments.removeTask(v.Task) {
oneModification()
}
removeTasks[v.Task.ID] = struct{}{}
delete(tasksMap, v.Task.ID)
// Release the secrets being used by this task
// Ignoring the return here. We will always mark
// this as a modification, since a task is being
// removed.
releaseSecretsForTask(v.Task)
oneModification()
// TODO(aaronl): For node secrets, we'll need to handle
// EventCreateSecret.
case api.EventUpdateSecret:
if _, exists := tasksUsingSecret[v.Secret.ID]; !exists {
continue
}
log.Debugf("Secret %s (ID: %d) was updated though it was still referenced by one or more tasks",
v.Secret.Spec.Annotations.Name, v.Secret.ID)
case api.EventDeleteSecret:
if _, exists := tasksUsingSecret[v.Secret.ID]; !exists {
continue
}
log.Debugf("Secret %s (ID: %d) was deleted though it was still referenced by one or more tasks",
v.Secret.Spec.Annotations.Name, v.Secret.ID)
// TODO(aaronl): For node secrets, we'll need to handle
// EventCreateSecret.
}
case <-batchingTimeout:
break batchingLoop
@ -1083,72 +937,7 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
}
if modificationCnt > 0 {
for id, task := range updateTasks {
if _, ok := removeTasks[id]; !ok {
taskChange := &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Task{
Task: task,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
update.Changes = append(update.Changes, taskChange)
}
}
for id, secret := range updateSecrets {
// If, due to multiple updates, this secret is no longer in use,
// don't send it down.
if len(tasksUsingSecret[id]) == 0 {
// delete this secret for the secrets to be updated
// so that deleteSecrets knows the current list
delete(updateSecrets, id)
continue
}
secretChange := &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Secret{
Secret: secret,
},
},
Action: api.AssignmentChange_AssignmentActionUpdate,
}
update.Changes = append(update.Changes, secretChange)
}
for id := range removeTasks {
taskChange := &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Task{
Task: &api.Task{ID: id},
},
},
Action: api.AssignmentChange_AssignmentActionRemove,
}
update.Changes = append(update.Changes, taskChange)
}
for id := range removeSecrets {
// If this secret is also being sent on the updated set
// don't also add it to the removed set
if _, ok := updateSecrets[id]; ok {
continue
}
secretChange := &api.AssignmentChange{
Assignment: &api.Assignment{
Item: &api.Assignment_Secret{
Secret: &api.Secret{ID: id},
},
},
Action: api.AssignmentChange_AssignmentActionRemove,
}
update.Changes = append(update.Changes, secretChange)
}
if err := sendMessage(update, api.AssignmentsMessage_INCREMENTAL); err != nil {
if err := sendMessage(assignments.message(), api.AssignmentsMessage_INCREMENTAL); err != nil {
return err
}
}
@ -1284,6 +1073,12 @@ func (d *Dispatcher) getNetworkBootstrapKeys() []*api.EncryptionKey {
return d.networkBootstrapKeys
}
func (d *Dispatcher) getRootCACert() []byte {
d.mu.Lock()
defer d.mu.Unlock()
return d.lastSeenRootCert
}
// Session is a stream which controls agent connection.
// Each message contains list of backup Managers with weights. Also there is
// 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
Node: nodeObj,
Managers: d.getManagers(),
NetworkBootstrapKeys: d.getNetworkBootstrapKeys(),
RootCA: d.getRootCACert(),
}); err != nil {
return err
}
managerUpdates, mgrCancel := d.mgrQueue.Watch()
defer mgrCancel()
keyMgrUpdates, keyMgrCancel := d.keyMgrQueue.Watch()
defer keyMgrCancel()
clusterUpdatesCh, clusterCancel := d.clusterUpdateQueue.Watch()
defer clusterCancel()
// disconnectNode is a helper forcibly shutdown connection
disconnectNode := func() error {
@ -1396,11 +1190,21 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
disconnect bool
mgrs []*api.WeightedPeer
netKeys []*api.EncryptionKey
rootCert []byte
)
select {
case ev := <-managerUpdates:
mgrs = ev.([]*api.WeightedPeer)
case ev := <-clusterUpdatesCh:
update := ev.(clusterUpdate)
if update.managerUpdate != nil {
mgrs = *update.managerUpdate
}
if update.bootstrapKeyUpdate != nil {
netKeys = *update.bootstrapKeyUpdate
}
if update.rootCAUpdate != nil {
rootCert = *update.rootCAUpdate
}
case ev := <-nodeUpdates:
nodeObj = ev.(api.EventUpdateNode).Node
case <-stream.Context().Done():
@ -1409,8 +1213,6 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
disconnect = true
case <-dctx.Done():
disconnect = true
case ev := <-keyMgrUpdates:
netKeys = ev.([]*api.EncryptionKey)
}
if mgrs == nil {
mgrs = d.getManagers()
@ -1418,12 +1220,16 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
if netKeys == nil {
netKeys = d.getNetworkBootstrapKeys()
}
if rootCert == nil {
rootCert = d.getRootCACert()
}
if err := stream.Send(&api.SessionMessage{
SessionID: sessionID,
Node: nodeObj,
Managers: mgrs,
NetworkBootstrapKeys: netKeys,
RootCA: rootCert,
}); err != nil {
return err
}

View file

@ -65,6 +65,9 @@ type RemoteAddrs struct {
type Config struct {
SecurityConfig *ca.SecurityConfig
// RootCAPaths is the path to which new root certs should be save
RootCAPaths ca.CertPaths
// ExternalCAs is a list of initial CAs to which a manager node
// will make certificate signing requests for node certificates.
ExternalCAs []*api.ExternalCA
@ -210,7 +213,7 @@ func New(config *Config) (*Manager, error) {
m := &Manager{
config: *config,
caserver: ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig),
caserver: ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig, config.RootCAPaths),
dispatcher: dispatcher.New(raftNode, dispatcher.DefaultConfig()),
logbroker: logbroker.New(raftNode.MemoryStore()),
server: grpc.NewServer(opts...),

View file

@ -5,6 +5,7 @@ import (
"time"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/defaults"
"github.com/docker/swarmkit/identity"
"github.com/docker/swarmkit/protobuf/ptypes"
)
@ -50,7 +51,7 @@ func NewTask(cluster *api.Cluster, service *api.Service, slot uint64, nodeID str
// RestartCondition returns the restart condition to apply to this task.
func RestartCondition(task *api.Task) api.RestartPolicy_RestartCondition {
restartCondition := api.RestartOnAny
restartCondition := defaults.Service.Task.Restart.Condition
if task.Spec.Restart != nil {
restartCondition = task.Spec.Restart.Condition
}

View file

@ -155,31 +155,25 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
u.startUpdate(ctx, service.ID)
}
delay := defaults.Service.Update.Delay
parallelism := int(defaults.Service.Update.Parallelism)
failureAction := defaults.Service.Update.FailureAction
allowedFailureFraction := defaults.Service.Update.MaxFailureRatio
monitoringPeriod, _ := gogotypes.DurationFromProto(defaults.Service.Update.Monitor)
order := defaults.Service.Update.Order
var monitoringPeriod time.Duration
updateConfig := service.Spec.Update
if service.UpdateStatus != nil && service.UpdateStatus.State == api.UpdateStatus_ROLLBACK_STARTED {
monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Rollback.Monitor)
updateConfig = service.Spec.Rollback
if updateConfig == nil {
updateConfig = defaults.Service.Rollback
}
} else if updateConfig == nil {
monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Update.Monitor)
updateConfig = defaults.Service.Update
}
if updateConfig != nil {
failureAction = updateConfig.FailureAction
allowedFailureFraction = updateConfig.MaxFailureRatio
parallelism = int(updateConfig.Parallelism)
delay = updateConfig.Delay
order = updateConfig.Order
var err error
if updateConfig.Monitor != nil {
monitoringPeriod, err = gogotypes.DurationFromProto(updateConfig.Monitor)
if err != nil {
monitoringPeriod, _ = gogotypes.DurationFromProto(defaults.Service.Update.Monitor)
}
parallelism := int(updateConfig.Parallelism)
if updateConfig.Monitor != nil {
newMonitoringPeriod, err := gogotypes.DurationFromProto(updateConfig.Monitor)
if err == nil {
monitoringPeriod = newMonitoringPeriod
}
}
@ -195,14 +189,14 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
wg.Add(parallelism)
for i := 0; i < parallelism; i++ {
go func() {
u.worker(ctx, slotQueue, delay, order)
u.worker(ctx, slotQueue, updateConfig)
wg.Done()
}()
}
var failedTaskWatch chan events.Event
if failureAction != api.UpdateConfig_CONTINUE {
if updateConfig.FailureAction != api.UpdateConfig_CONTINUE {
var cancelWatch func()
failedTaskWatch, cancelWatch = state.Watch(
u.store.WatchQueue(),
@ -234,8 +228,8 @@ func (u *Updater) Run(ctx context.Context, slots []orchestrator.Slot) {
if found && (startedAt.IsZero() || time.Since(startedAt) <= monitoringPeriod) {
failedTasks[failedTask.ID] = struct{}{}
totalFailures++
if float32(totalFailures)/float32(len(dirtySlots)) > allowedFailureFraction {
switch failureAction {
if float32(totalFailures)/float32(len(dirtySlots)) > updateConfig.MaxFailureRatio {
switch updateConfig.FailureAction {
case api.UpdateConfig_PAUSE:
stopped = true
message := fmt.Sprintf("update paused due to failure or early termination of task %s", failedTask.ID)
@ -309,7 +303,7 @@ slotsLoop:
}
}
func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot, delay time.Duration, order api.UpdateConfig_UpdateOrder) {
func (u *Updater) worker(ctx context.Context, queue <-chan orchestrator.Slot, updateConfig *api.UpdateConfig) {
for slot := range queue {
// Do we have a task with the new spec in desired state = RUNNING?
// 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
}
updated.DesiredState = api.TaskStateReady
if err := u.updateTask(ctx, slot, updated, order); err != nil {
if err := u.updateTask(ctx, slot, updated, updateConfig.Order); err != nil {
log.G(ctx).WithError(err).WithField("task.id", updated.ID).Error("update failed")
}
}
if delay != 0 {
if updateConfig.Delay != 0 {
select {
case <-time.After(delay):
case <-time.After(updateConfig.Delay):
case <-u.stopChan:
return
}

View file

@ -154,6 +154,17 @@ func ByReferencedSecretID(secretID string) By {
return byReferencedSecretID(secretID)
}
type byReferencedConfigID string
func (b byReferencedConfigID) isBy() {
}
// ByReferencedConfigID creates an object to pass to Find to search for a
// service or task that references a config with the given ID.
func ByReferencedConfigID(configID string) By {
return byReferencedConfigID(configID)
}
type byKind string
func (b byKind) isBy() {

View file

@ -0,0 +1,132 @@
package store
import (
"strings"
"github.com/docker/swarmkit/api"
memdb "github.com/hashicorp/go-memdb"
)
const tableConfig = "config"
func init() {
register(ObjectStoreConfig{
Table: &memdb.TableSchema{
Name: tableConfig,
Indexes: map[string]*memdb.IndexSchema{
indexID: {
Name: indexID,
Unique: true,
Indexer: api.ConfigIndexerByID{},
},
indexName: {
Name: indexName,
Unique: true,
Indexer: api.ConfigIndexerByName{},
},
indexCustom: {
Name: indexCustom,
Indexer: api.ConfigCustomIndexer{},
AllowMissing: true,
},
},
},
Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error {
var err error
snapshot.Configs, err = FindConfigs(tx, All)
return err
},
Restore: func(tx Tx, snapshot *api.StoreSnapshot) error {
configs, err := FindConfigs(tx, All)
if err != nil {
return err
}
for _, s := range configs {
if err := DeleteConfig(tx, s.ID); err != nil {
return err
}
}
for _, s := range snapshot.Configs {
if err := CreateConfig(tx, s); err != nil {
return err
}
}
return nil
},
ApplyStoreAction: func(tx Tx, sa api.StoreAction) error {
switch v := sa.Target.(type) {
case *api.StoreAction_Config:
obj := v.Config
switch sa.Action {
case api.StoreActionKindCreate:
return CreateConfig(tx, obj)
case api.StoreActionKindUpdate:
return UpdateConfig(tx, obj)
case api.StoreActionKindRemove:
return DeleteConfig(tx, obj.ID)
}
}
return errUnknownStoreAction
},
})
}
// CreateConfig adds a new config to the store.
// Returns ErrExist if the ID is already taken.
func CreateConfig(tx Tx, c *api.Config) error {
// Ensure the name is not already in use.
if tx.lookup(tableConfig, indexName, strings.ToLower(c.Spec.Annotations.Name)) != nil {
return ErrNameConflict
}
return tx.create(tableConfig, c)
}
// UpdateConfig updates an existing config in the store.
// Returns ErrNotExist if the config doesn't exist.
func UpdateConfig(tx Tx, c *api.Config) error {
// Ensure the name is either not in use or already used by this same Config.
if existing := tx.lookup(tableConfig, indexName, strings.ToLower(c.Spec.Annotations.Name)); existing != nil {
if existing.GetID() != c.ID {
return ErrNameConflict
}
}
return tx.update(tableConfig, c)
}
// DeleteConfig removes a config from the store.
// Returns ErrNotExist if the config doesn't exist.
func DeleteConfig(tx Tx, id string) error {
return tx.delete(tableConfig, id)
}
// GetConfig looks up a config by ID.
// Returns nil if the config doesn't exist.
func GetConfig(tx ReadTx, id string) *api.Config {
c := tx.get(tableConfig, id)
if c == nil {
return nil
}
return c.(*api.Config)
}
// FindConfigs selects a set of configs and returns them.
func FindConfigs(tx ReadTx, by By) ([]*api.Config, error) {
checkType := func(by By) error {
switch by.(type) {
case byName, byNamePrefix, byIDPrefix, byCustom, byCustomPrefix:
return nil
default:
return ErrInvalidFindBy
}
}
configList := []*api.Config{}
appendResult := func(o api.StoreObject) {
configList = append(configList, o.(*api.Config))
}
err := tx.find(tableConfig, by, checkType, appendResult)
return configList, err
}

View file

@ -33,6 +33,7 @@ const (
indexMembership = "membership"
indexNetwork = "network"
indexSecret = "secret"
indexConfig = "config"
indexKind = "kind"
indexCustom = "custom"
@ -696,6 +697,12 @@ func (tx readTx) findIterators(table string, by By, checkType func(By) error) ([
return nil, err
}
return []memdb.ResultIterator{it}, nil
case byReferencedConfigID:
it, err := tx.memDBTx.Get(table, indexConfig, string(v))
if err != nil {
return nil, err
}
return []memdb.ResultIterator{it}, nil
case byKind:
it, err := tx.memDBTx.Get(table, indexKind, string(v))
if err != nil {

View file

@ -40,6 +40,11 @@ func init() {
AllowMissing: true,
Indexer: serviceIndexerBySecret{},
},
indexConfig: {
Name: indexConfig,
AllowMissing: true,
Indexer: serviceIndexerByConfig{},
},
indexCustom: {
Name: indexCustom,
Indexer: api.ServiceCustomIndexer{},
@ -131,7 +136,7 @@ func GetService(tx ReadTx, id string) *api.Service {
func FindServices(tx ReadTx, by By) ([]*api.Service, error) {
checkType := func(by By) error {
switch by.(type) {
case byName, byNamePrefix, byIDPrefix, byRuntime, byReferencedNetworkID, byReferencedSecretID, byCustom, byCustomPrefix:
case byName, byNamePrefix, byIDPrefix, byRuntime, byReferencedNetworkID, byReferencedSecretID, byReferencedConfigID, byCustom, byCustomPrefix:
return nil
default:
return ErrInvalidFindBy
@ -214,3 +219,30 @@ func (si serviceIndexerBySecret) FromObject(obj interface{}) (bool, [][]byte, er
return len(secretIDs) != 0, secretIDs, nil
}
type serviceIndexerByConfig struct{}
func (si serviceIndexerByConfig) FromArgs(args ...interface{}) ([]byte, error) {
return fromArgs(args...)
}
func (si serviceIndexerByConfig) FromObject(obj interface{}) (bool, [][]byte, error) {
s, ok := obj.(*api.Service)
if !ok {
panic("unexpected type passed to FromObject")
}
container := s.Spec.Task.GetContainer()
if container == nil {
return false, nil, nil
}
var configIDs [][]byte
for _, configRef := range container.Configs {
// Add the null character as a terminator
configIDs = append(configIDs, []byte(configRef.ConfigID+"\x00"))
}
return len(configIDs) != 0, configIDs, nil
}

View file

@ -64,6 +64,11 @@ func init() {
AllowMissing: true,
Indexer: taskIndexerBySecret{},
},
indexConfig: {
Name: indexConfig,
AllowMissing: true,
Indexer: taskIndexerByConfig{},
},
indexCustom: {
Name: indexCustom,
Indexer: api.TaskCustomIndexer{},
@ -143,7 +148,7 @@ func GetTask(tx ReadTx, id string) *api.Task {
func FindTasks(tx ReadTx, by By) ([]*api.Task, error) {
checkType := func(by By) error {
switch by.(type) {
case byName, byNamePrefix, byIDPrefix, byRuntime, byDesiredState, byTaskState, byNode, byService, bySlot, byReferencedNetworkID, byReferencedSecretID, byCustom, byCustomPrefix:
case byName, byNamePrefix, byIDPrefix, byRuntime, byDesiredState, byTaskState, byNode, byService, bySlot, byReferencedNetworkID, byReferencedSecretID, byReferencedConfigID, byCustom, byCustomPrefix:
return nil
default:
return ErrInvalidFindBy
@ -295,6 +300,33 @@ func (ti taskIndexerBySecret) FromObject(obj interface{}) (bool, [][]byte, error
return len(secretIDs) != 0, secretIDs, nil
}
type taskIndexerByConfig struct{}
func (ti taskIndexerByConfig) FromArgs(args ...interface{}) ([]byte, error) {
return fromArgs(args...)
}
func (ti taskIndexerByConfig) FromObject(obj interface{}) (bool, [][]byte, error) {
t, ok := obj.(*api.Task)
if !ok {
panic("unexpected type passed to FromObject")
}
container := t.Spec.GetContainer()
if container == nil {
return false, nil, nil
}
var configIDs [][]byte
for _, configRef := range container.Configs {
// Add the null character as a terminator
configIDs = append(configIDs, []byte(configRef.ConfigID+"\x00"))
}
return len(configIDs) != 0, configIDs, nil
}
type taskIndexerByTaskState struct{}
func (ts taskIndexerByTaskState) FromArgs(args ...interface{}) ([]byte, error) {

View file

@ -1,6 +1,7 @@
package node
import (
"bytes"
"crypto/tls"
"encoding/json"
"io/ioutil"
@ -25,6 +26,7 @@ import (
"github.com/docker/swarmkit/manager"
"github.com/docker/swarmkit/manager/encryption"
"github.com/docker/swarmkit/remotes"
"github.com/docker/swarmkit/watch"
"github.com/docker/swarmkit/xnet"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/pkg/errors"
@ -129,7 +131,7 @@ type Node struct {
err error
agent *agent.Agent
manager *manager.Manager
notifyNodeChange chan *api.Node // used to send role updates from the dispatcher api on promotion/demotion
notifyNodeChange chan *agent.NodeChanges // used by the agent to relay node updates from the dispatcher Session stream to (*Node).run
unlockKey []byte
}
@ -172,7 +174,7 @@ func New(c *Config) (*Node, error) {
stopped: make(chan struct{}),
closed: make(chan struct{}),
ready: make(chan struct{}),
notifyNodeChange: make(chan *api.Node, 1),
notifyNodeChange: make(chan *agent.NodeChanges, 1),
unlockKey: c.UnlockKey,
}
@ -235,7 +237,8 @@ func (n *Node) run(ctx context.Context) (err error) {
}
}(ctx)
securityConfig, err := n.loadSecurityConfig(ctx)
paths := ca.NewConfigPaths(filepath.Join(n.config.StateDir, certDirectory))
securityConfig, err := n.loadSecurityConfig(ctx, paths)
if err != nil {
return err
}
@ -274,24 +277,44 @@ func (n *Node) run(ctx context.Context) (err error) {
select {
case <-agentDone:
return
case node := <-n.notifyNodeChange:
// If the server is sending us a ForceRenewal State, renew
if node.Certificate.Status.State == api.IssuanceStateRotate {
renewCert()
continue
}
case nodeChanges := <-n.notifyNodeChange:
n.Lock()
// If we got a role change, renew
role := ca.WorkerRole
if node.Role == api.NodeRoleManager {
role = ca.ManagerRole
}
if n.role == role {
n.Unlock()
continue
}
currentRole := n.role
n.Unlock()
renewCert()
if nodeChanges.Node != nil {
role := ca.WorkerRole
if nodeChanges.Node.Role == api.NodeRoleManager {
role = ca.ManagerRole
}
// If the server is sending us a ForceRenewal State, or if the new node role doesn't match our current role, renew
if currentRole != role || nodeChanges.Node.Certificate.Status.State == api.IssuanceStateRotate {
renewCert()
}
}
if nodeChanges.RootCert != nil {
// We only want to update the root CA if this is a worker node. Manager nodes directly watch the raft
// store and update the root CA, with the necessary signer, from the raft store (since the managers
// need the CA key as well to potentially issue new TLS certificates).
if currentRole == ca.ManagerRole || bytes.Equal(nodeChanges.RootCert, securityConfig.RootCA().Certs) {
continue
}
newRootCA, err := ca.NewRootCA(nodeChanges.RootCert, nil, nil, ca.DefaultNodeCertExpiration, nil)
if err != nil {
log.G(ctx).WithError(err).Error("invalid new root certificate from the dispatcher")
continue
}
if err := ca.SaveRootCA(newRootCA, paths.RootCA); err != nil {
log.G(ctx).WithError(err).Error("could not save new root certificate from the dispatcher")
continue
}
if err := securityConfig.UpdateRootCA(&newRootCA, newRootCA.Pool); err != nil {
log.G(ctx).WithError(err).Error("could not use new root CA from dispatcher")
continue
}
}
}
}
}()
@ -322,12 +345,12 @@ func (n *Node) run(ctx context.Context) (err error) {
var managerErr error
var agentErr error
go func() {
managerErr = n.superviseManager(ctx, securityConfig, managerReady, forceCertRenewal) // store err and loop
managerErr = n.superviseManager(ctx, securityConfig, paths.RootCA, managerReady, forceCertRenewal) // store err and loop
wg.Done()
cancel()
}()
go func() {
agentErr = n.runAgent(ctx, db, securityConfig.ClientTLSCreds, agentReady)
agentErr = n.runAgent(ctx, db, securityConfig, agentReady)
wg.Done()
cancel()
close(agentDone)
@ -401,7 +424,7 @@ func (n *Node) Err(ctx context.Context) error {
}
}
func (n *Node) runAgent(ctx context.Context, db *bolt.DB, creds credentials.TransportCredentials, ready chan<- struct{}) error {
func (n *Node) runAgent(ctx context.Context, db *bolt.DB, securityConfig *ca.SecurityConfig, ready chan<- struct{}) error {
waitCtx, waitCancel := context.WithCancel(ctx)
remotesCh := n.remotes.WaitSelect(ctx)
controlCh := n.ListenControlSocket(waitCtx)
@ -428,13 +451,28 @@ waitPeer:
default:
}
secChangeQueue := watch.NewQueue()
defer secChangeQueue.Close()
secChangesCh, secChangesCancel := secChangeQueue.Watch()
defer secChangesCancel()
securityConfig.SetWatch(secChangeQueue)
rootCA := securityConfig.RootCA()
issuer := securityConfig.IssuerInfo()
a, err := agent.New(&agent.Config{
Hostname: n.config.Hostname,
ConnBroker: n.connBroker,
Executor: n.config.Executor,
DB: db,
NotifyNodeChange: n.notifyNodeChange,
Credentials: creds,
NotifyTLSChange: secChangesCh,
Credentials: securityConfig.ClientTLSCreds,
NodeTLSInfo: &api.NodeTLSInfo{
TrustRoot: rootCA.Certs,
CertIssuerPublicKey: issuer.PublicKey,
CertIssuerSubject: issuer.Subject,
},
})
if err != nil {
return err
@ -565,8 +603,7 @@ func (n *Node) Remotes() []api.Peer {
return remotes
}
func (n *Node) loadSecurityConfig(ctx context.Context) (*ca.SecurityConfig, error) {
paths := ca.NewConfigPaths(filepath.Join(n.config.StateDir, certDirectory))
func (n *Node) loadSecurityConfig(ctx context.Context, paths *ca.SecurityConfigPaths) (*ca.SecurityConfig, error) {
var securityConfig *ca.SecurityConfig
krw := ca.NewKeyReadWriter(paths.Node, n.unlockKey, &manager.RaftDEKData{})
@ -717,7 +754,7 @@ func (n *Node) waitRole(ctx context.Context, role string) error {
return nil
}
func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, workerRole <-chan struct{}) (bool, error) {
func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig, rootPaths ca.CertPaths, ready chan struct{}, workerRole <-chan struct{}) (bool, error) {
var remoteAPI *manager.RemoteAddrs
if n.config.ListenRemoteAPI != "" {
remoteAPI = &manager.RemoteAddrs{
@ -741,6 +778,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
UnlockKey: n.unlockKey,
Availability: n.config.Availability,
PluginGetter: n.config.PluginGetter,
RootCAPaths: rootPaths,
})
if err != nil {
return false, err
@ -789,7 +827,7 @@ func (n *Node) runManager(ctx context.Context, securityConfig *ca.SecurityConfig
return clearData, nil
}
func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, ready chan struct{}, forceCertRenewal chan struct{}) error {
func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.SecurityConfig, rootPaths ca.CertPaths, ready chan struct{}, forceCertRenewal chan struct{}) error {
for {
if err := n.waitRole(ctx, ca.ManagerRole); err != nil {
return err
@ -803,7 +841,7 @@ func (n *Node) superviseManager(ctx context.Context, securityConfig *ca.Security
}
}()
wasRemoved, err := n.runManager(ctx, securityConfig, ready, workerRole)
wasRemoved, err := n.runManager(ctx, securityConfig, rootPaths, ready, workerRole)
if err != nil {
waitRoleCancel()
return errors.Wrap(err, "manager stopped")