syntax = "proto3";

package docker.swarmkit.v1;

import "github.com/docker/swarmkit/api/specs.proto";
import "github.com/docker/swarmkit/api/objects.proto";
import "github.com/docker/swarmkit/api/types.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";

// Control defines the RPC methods for controlling a cluster.
service Control {
	rpc GetNode(GetNodeRequest) returns (GetNodeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc ListNodes(ListNodesRequest) returns (ListNodesResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc UpdateNode(UpdateNodeRequest) returns (UpdateNodeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc RemoveNode(RemoveNodeRequest) returns (RemoveNodeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	rpc GetTask(GetTaskRequest) returns (GetTaskResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc ListTasks(ListTasksRequest) returns (ListTasksResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc RemoveTask(RemoveTaskRequest) returns (RemoveTaskResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	rpc GetService(GetServiceRequest) returns (GetServiceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc ListServices(ListServicesRequest) returns (ListServicesResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc CreateService(CreateServiceRequest) returns (CreateServiceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc UpdateService(UpdateServiceRequest) returns (UpdateServiceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc RemoveService(RemoveServiceRequest) returns (RemoveServiceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	// ListServiceStatuses returns a `ListServiceStatusesResponse` with the
	// status of the requested services, formed by computing the number of
	// running vs desired tasks. It is provided as a shortcut or helper method,
	// which allows a client to avoid having to calculate this value by listing
	// all Tasks. If any service requested does not exist, it will be returned
	// but with empty status values.
	rpc ListServiceStatuses(ListServiceStatusesRequest) returns (ListServiceStatusesResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	rpc GetNetwork(GetNetworkRequest) returns (GetNetworkResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc ListNetworks(ListNetworksRequest) returns (ListNetworksResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc CreateNetwork(CreateNetworkRequest) returns (CreateNetworkResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc RemoveNetwork(RemoveNetworkRequest) returns (RemoveNetworkResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	rpc GetCluster(GetClusterRequest) returns (GetClusterResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc ListClusters(ListClustersRequest) returns (ListClustersResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};
	rpc UpdateCluster(UpdateClusterRequest) returns (UpdateClusterResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	// --- secret APIs ---

	// GetSecret returns a `GetSecretResponse` with a `Secret` with the same
	// id as `GetSecretRequest.SecretID`
	// - Returns `NotFound` if the Secret with the given id is not found.
	// - Returns `InvalidArgument` if the `GetSecretRequest.SecretID` is empty.
	// - Returns an error if getting fails.
	rpc GetSecret(GetSecretRequest) returns (GetSecretResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// UpdateSecret returns a `UpdateSecretResponse` with a `Secret` with the same
	// id as `GetSecretRequest.SecretID`
	// - Returns `NotFound` if the Secret with the given id is not found.
	// - Returns `InvalidArgument` if the `GetSecretRequest.SecretID` is empty.
	// - Returns an error if updating fails.
	rpc UpdateSecret(UpdateSecretRequest) returns (UpdateSecretResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	};

	// 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`.
	// - Returns an error if listing fails.
	rpc ListSecrets(ListSecretsRequest) returns (ListSecretsResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}
	// CreateSecret creates and return a `CreateSecretResponse` with a `Secret` based
	// on the provided `CreateSecretRequest.SecretSpec`.
	// - Returns `InvalidArgument` if the `CreateSecretRequest.SecretSpec` is malformed,
	//   or if the secret data is too long or contains invalid characters.
	// - Returns an error if the creation fails.
	rpc CreateSecret(CreateSecretRequest) returns (CreateSecretResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// RemoveSecret removes the secret referenced by `RemoveSecretRequest.ID`.
	// - Returns `InvalidArgument` if `RemoveSecretRequest.ID` is empty.
	// - Returns `NotFound` if the a secret named `RemoveSecretRequest.ID` is not found.
	// - Returns an error if the deletion fails.
	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" };
	}

	// --- extension APIs ---

	// GetExtension returns a `GetExtensionResponse` with a `Extension` with the same
	// id as `GetExtensionRequest.ExtensionId`
	// - Returns `NotFound` if the Extension with the given id is not found.
	// - Returns `InvalidArgument` if the `GetExtensionRequest.ExtensionId` is empty.
	// - Returns an error if the get fails.
	rpc GetExtension(GetExtensionRequest) returns (GetExtensionResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// CreateExtension creates an `Extension` based on the provided `CreateExtensionRequest.Extension`
	// and returns a `CreateExtensionResponse`.
	// - Returns `InvalidArgument` if the `CreateExtensionRequest.Extension` is malformed,
	//   or fails validation.
	// - Returns an error if the creation fails.
	rpc CreateExtension(CreateExtensionRequest) returns (CreateExtensionResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// RemoveExtension removes the extension referenced by `RemoveExtensionRequest.ID`.
	// - Returns `InvalidArgument` if `RemoveExtensionRequest.ExtensionId` is empty.
	// - Returns `NotFound` if the an extension named `RemoveExtensionRequest.ExtensionId` is not found.
	// - Returns an error if the deletion fails.
	rpc RemoveExtension(RemoveExtensionRequest) returns (RemoveExtensionResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// --- resource APIs ---

	// GetResource returns a `GetResourceResponse` with a `Resource` with the same
	// id as `GetResourceRequest.Resource`
	// - Returns `NotFound` if the Resource with the given id is not found.
	// - Returns `InvalidArgument` if the `GetResourceRequest.Resource` is empty.
	// - Returns an error if getting fails.
	rpc GetResource(GetResourceRequest) returns (GetResourceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// UpdateResource updates the resource with the given `UpdateResourceRequest.Resource.Id` using the given `UpdateResourceRequest.Resource` and returns a `UpdateResourceResponse`.
	// - Returns `NotFound` if the Resource with the given `UpdateResourceRequest.Resource.Id` is not found.
	// - Returns `InvalidArgument` if the UpdateResourceRequest.Resource.Id` is empty.
	// - Returns an error if updating fails.
	rpc UpdateResource(UpdateResourceRequest) returns (UpdateResourceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// ListResources returns a `ListResourcesResponse` with a list of `Resource`s stored in the raft store,
	// or all resources matching any name in `ListConfigsRequest.Names`, any
	// name prefix in `ListResourcesRequest.NamePrefixes`, any id in
	// `ListResourcesRequest.ResourceIDs`, or any id prefix in `ListResourcesRequest.IDPrefixes`,
	// extension name equal to `ListResourcesRequest.Extension`.
	// - Returns an error if listing fails.
	rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// CreateResource returns a `CreateResourceResponse` after creating a `Resource` based
	// on the provided `CreateResourceRequest.Resource`.
	// - Returns `InvalidArgument` if the `CreateResourceRequest.Resource` is malformed,
	//   or if the config data is too long or contains invalid characters.
	// - Returns an error if the creation fails.
	rpc CreateResource(CreateResourceRequest) returns (CreateResourceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// RemoveResource removes the `Resource` referenced by `RemoveResourceRequest.ResourceID`.
	// - Returns `InvalidArgument` if `RemoveResourceRequest.ResourceID` is empty.
	// - Returns `NotFound` if the a resource named `RemoveResourceRequest.ResourceID` is not found.
	// - Returns an error if the deletion fails.
	rpc RemoveResource(RemoveResourceRequest) returns (RemoveResourceResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// --- volumes APIs ---

	// CreateVolume returns a `CreateVolumeResponse` with a `Volume` based on the
	// provided `CreateVolumeRequest.VolumeSpec`.
	// - Returns `InvalidArgument` if the `CreateVolumeRequest.VolumeSpec` is
	//   malformed.
	rpc CreateVolume(CreateVolumeRequest) returns (CreateVolumeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	// GetVolume returns a `GetVolumeResponse` with a Volume with the same ID
	// as `GetVolumeRequest.ID`
	rpc GetVolume(GetVolumeRequest) returns (GetVolumeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	rpc UpdateVolume(UpdateVolumeRequest) returns (UpdateVolumeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}

	rpc RemoveVolume(RemoveVolumeRequest) returns (RemoveVolumeResponse) {
		option (docker.protobuf.plugin.tls_authorization) = { roles: "swarm-manager" };
	}
}

message GetNodeRequest {
	string node_id = 1;
}

message GetNodeResponse {
	Node node = 1;
}

message ListNodesRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		// Labels refers to engine labels, which are labels set by the user on the
		// node and reported back to the managers
		map<string, string> labels = 3;
		// NodeLabels are labels set on the node object on the managers.
		map<string, string> node_labels = 7;
		repeated NodeSpec.Membership memberships = 4 [packed=false];
		repeated NodeRole roles = 5 [packed=false];
		// NamePrefixes matches all objects with the given prefixes
		repeated string name_prefixes = 6;
	}

	Filters filters = 1;
}

message ListNodesResponse {
	repeated Node nodes = 1;
}

// UpdateNodeRequest requests an update to the specified node. This may be used
// to request a new availability for a node, such as PAUSE. Invalid updates
// will be denied and cause an error.
message UpdateNodeRequest {
	string node_id = 1;
	Version node_version = 2;
	NodeSpec spec = 3;
}

message UpdateNodeResponse {
	Node node = 1;
}

// RemoveNodeRequest requests to delete the specified node from store.
message RemoveNodeRequest {
	string node_id = 1;
	bool force = 2;
}

message RemoveNodeResponse {
}

message GetTaskRequest {
	string task_id = 1;
}

message GetTaskResponse {
	Task task = 1;
}

message RemoveTaskRequest {
	string task_id = 1;
}

message RemoveTaskResponse {
}

message ListTasksRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		repeated string service_ids = 4;
		repeated string node_ids = 5;
		repeated docker.swarmkit.v1.TaskState desired_states = 6 [packed=false];
		// NamePrefixes matches all objects with the given prefixes
		repeated string name_prefixes = 7;
		repeated string runtimes = 9;

		// UpToDate matches tasks that are consistent with the current
		// service definition.
		// Note: this is intended for internal status reporting rather
		// than being exposed to users. It may be removed in the future.
		bool up_to_date = 8;
	}

	Filters filters = 1;
}

message ListTasksResponse {
	repeated Task tasks = 1;
}

message CreateServiceRequest {
	ServiceSpec spec = 1;
}

message CreateServiceResponse {
	Service service = 1;
}

message GetServiceRequest {
	string service_id = 1;
	bool insert_defaults = 2;
}

message GetServiceResponse {
	Service service = 1;
}

message UpdateServiceRequest {
	string service_id = 1;
	Version service_version = 2;
	ServiceSpec spec = 3;

	enum Rollback {
		// This is not a rollback. The spec field of the request will
		// be honored.
		NONE = 0;

		// Roll back the service - get spec from the service's
		// previous_spec.
		PREVIOUS = 1;
	}

	// Rollback may be set to PREVIOUS to request a rollback (the service's
	// spec will be set to the value of its previous_spec field). In this
	// case, the spec field of this request is ignored.
	Rollback rollback = 4;
}

message UpdateServiceResponse {
	Service service = 1;
}

message RemoveServiceRequest {
	string service_id = 1;
}

message RemoveServiceResponse {
}

message ListServicesRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		// NamePrefixes matches all objects with the given prefixes
		repeated string name_prefixes = 4;
		repeated string runtimes = 5;
	}

	Filters filters = 1;
}

message ListServicesResponse {
	repeated Service services = 1;
}

// ListServiceStatusesRequest is a request to get the aggregate status of a
// service by computing the number of running vs desired tasks. It includes
// only a service ID.
message ListServiceStatusesRequest {
	// Services is a list of service IDs to get statuses for.
	repeated string services = 1;
}

// ListServiceStatusesResponse is a response containing the aggregate status of
// a service, formed by computing the number of running vs desired tasks. The
// values returned are only valid for the point in time at which the request is
// made.
message ListServiceStatusesResponse {
	message ServiceStatus {
		// ServiceID is the ID of the service this status describes
		string service_id = 1;

		// DesiredTasks is the number of tasks desired to be running according to the
		// service definition at request time. It is a uint64 because that is what
		// the replicas field on the service spec is
		uint64 desired_tasks = 2;
		
		// RunningTasks is the number of tasks currently in the Running state at
		// request time. This may be larger than desired tasks if, for example, a
		// service has been scaled down.
		uint64 running_tasks = 3;

		// CompletedTasks is the number of tasks in state Completed, if this
		// service is in mode ReplicatedJob or GlobalJob. This must be
		// cross-referenced with the service type, because the default value of 0
		// may mean that a service is not in a Job mode, or it may mean the Job has
		// yet to complete any Tasks.
		uint64 completed_tasks = 4;
	}

	repeated ServiceStatus statuses = 1;
}

message CreateNetworkRequest {
	NetworkSpec spec = 1;
}

message CreateNetworkResponse {
	Network network = 1;
}

message GetNetworkRequest {
	string name = 1;
	string network_id = 2;
}

message GetNetworkResponse {
	Network network = 1;
}

message RemoveNetworkRequest {
	string name = 1;
	string network_id = 2;
}

message RemoveNetworkResponse {}

message ListNetworksRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		// NamePrefixes matches all objects with the given prefixes
		repeated string name_prefixes = 4;
	}

	Filters filters = 1;
}

message ListNetworksResponse {
	repeated Network networks = 1;
}

message GetClusterRequest {
	string cluster_id = 1;
}

message GetClusterResponse {
	Cluster cluster = 1;
}

message ListClustersRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		// NamePrefixes matches all objects with the given prefixes
		repeated string name_prefixes = 4;
	}

	Filters filters = 1;
}

message ListClustersResponse {
	repeated Cluster clusters = 1;
}

// KeyRotation tells UpdateCluster what items to rotate
message KeyRotation {
	// WorkerJoinToken tells UpdateCluster to rotate the worker secret token.
	bool worker_join_token = 1;

	// ManagerJoinToken tells UpdateCluster to rotate the manager secret token.
	bool manager_join_token = 2;

	// ManagerUnlockKey tells UpdateCluster to rotate the manager unlock key
	bool manager_unlock_key = 3;

}

message UpdateClusterRequest {
	// ClusterID is the cluster ID to update.
	string cluster_id = 1;

	// ClusterVersion is the version of the cluster being updated.
	Version cluster_version = 2;

	// Spec is the new spec to apply to the cluster.
	ClusterSpec spec = 3;

	// Rotation contains flags for join token and unlock key rotation
	KeyRotation rotation = 4 [(gogoproto.nullable) = false];
}

message UpdateClusterResponse {
	Cluster cluster = 1;
}

// GetSecretRequest is the request to get a `Secret` object given a secret id.
message GetSecretRequest {
	string secret_id = 1;
}

// GetSecretResponse contains the Secret corresponding to the id in
// `GetSecretRequest`, but the `Secret.Spec.Data` field in each `Secret`
// object should be nil instead of actually containing the secret bytes.
message GetSecretResponse {
	Secret secret = 1;
}

message UpdateSecretRequest {
	// SecretID is the secret ID to update.
	string secret_id = 1;

	// SecretVersion is the version of the secret being updated.
	Version secret_version = 2;

	// Spec is the new spec to apply to the Secret
	// Only some fields are allowed to be updated.
	SecretSpec spec = 3;
}

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 {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		repeated string name_prefixes = 4;
	}

	Filters filters = 1;
}

// ListSecretResponse contains a list of all the secrets that match the name or
// name prefix filters provided in `ListSecretRequest`.  The `Secret.Spec.Data`
// field in each `Secret` object should be nil instead of actually containing
// the secret bytes.
message ListSecretsResponse {
	repeated Secret secrets = 1;
}

// CreateSecretRequest specifies a new secret (it will not update an existing
// secret) to create.
message CreateSecretRequest {
	SecretSpec spec = 1;
}

// 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 {
	Secret secret = 1;
}

// RemoveSecretRequest contains the ID of the secret that should be removed.  This
// removes all versions of the secret.
message RemoveSecretRequest {
	string secret_id = 1;
}

// 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 {}

// CreateExtensionRequest creates a new extension as specified by the provided
// parameters
message CreateExtensionRequest {
	Annotations annotations = 1;
	string description = 2;
}

// CreateExtensionResponse contains the newly created `Extension` corresponding
// to the parameters in the CreateExtensionRequest.
message CreateExtensionResponse {
	Extension extension = 1;
}

// RemoveExtensionRequest contains the ID of the extension that should be removed. This
// removes all versions of the extension.
message RemoveExtensionRequest {
	string extension_id = 1;
}

// RemoveExtensionResponse is an empty object indicating the successful removal
// of an extension.
message RemoveExtensionResponse {
}

// GetResourceRequest is the request to get a Extension object given a extension id.
message GetExtensionRequest {
	string extension_id = 1;
}

// GetExtensionResponse contains the Extension corresponding to the id in
// `GetExtensionRequest`.
message GetExtensionResponse {
	Extension extension = 1;
}

// CreateResourceRequest creates a new resource specified by the included
// resource object. An existing resource will not be updated.
message CreateResourceRequest {
	Annotations annotations = 1;
	string kind = 2;
	google.protobuf.Any payload = 3;
}

// CreateResourceResponse contains the newly created `Resource` corresponding
// to the resource in the CreateResourceRequest.
message CreateResourceResponse {
	Resource resource = 1;
}

// RemoveResourceRequest contains the ID of the resource that should be removed. This
// removes all versions of the resource.
message RemoveResourceRequest {
	string resource_id = 1;
}

// RemoveResourceResponse is an empty object indicating the successful removal
// of a resource.
message RemoveResourceResponse {
}

// UpdateResourceRequest updates the resource specified by the given resource object.
message UpdateResourceRequest {
	string resource_id = 1;
	Version resource_version = 2;
	// Annotations describes the annotations to update. If the Annotations should
	// be unchanged, then this field should be left empty. Note that the name of
	// a Resource cannot be changed, only its labels.
	Annotations annotations = 3;
	// Payload describes the new payload of the resource. If the Payload should
	// be unchanged, then this field should be left empty.
	google.protobuf.Any payload = 4;
}

message UpdateResourceResponse {
	Resource resource = 1;
}

// GetResourceRequest is the request to get a Resource object given a resource id.
message GetResourceRequest {
	string resource_id = 1;
}

// GetResourceResponse contains the Resource corresponding to the id in
// `GetResourceRequest`.
message GetResourceResponse {
	Resource resource = 1;
}

// ListResourcesRequest is the request to list all resources in the raft store,
// or all resources filtered by (name or name prefix or id prefix), labels and extension.
message ListResourcesRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		repeated string name_prefixes = 4;
		string kind = 5;
	}

	Filters filters = 1;
}

// ListResourcesResponse contains a list of all the resources that match the name or
// name prefix filters provided in `ListResourcesRequest`.
message ListResourcesResponse {
	repeated Resource resources = 1;
}

message CreateVolumeRequest {
	VolumeSpec spec = 1;
}

message CreateVolumeResponse {
	Volume volume = 1;
}

message GetVolumeRequest {
	string volume_id = 1;
}

message GetVolumeResponse {
	Volume volume = 1;
}

message UpdateVolumeRequest {
	string volume_id = 1;

	Version volume_version = 2;

	VolumeSpec spec = 3;
}

message UpdateVolumeResponse {
	Volume volume = 1;
}

message ListVolumesRequest {
	message Filters {
		repeated string names = 1;
		repeated string id_prefixes = 2;
		map<string, string> labels = 3;
		repeated string name_prefixes = 4;
		repeated string groups = 5;
		repeated string drivers = 6;
	}

	Filters filters = 1;
}

message ListVolumesResponse {
	repeated Volume volumes = 1;
}

message RemoveVolumeRequest {
	string volume_id = 1;
	// Force forces the volume to be deleted from swarmkit, regardless of
	// whether its current state would permit such an action.
	bool force = 2;
}

message RemoveVolumeResponse {}
