syntax = "proto3";

package yandex.cloud.mdb.mysql.v1alpha;

import "google/api/annotations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/type/timeofday.proto";
import "yandex/cloud/api/operation.proto";
import "yandex/cloud/operation/operation.proto";
import "yandex/cloud/validation.proto";
import "yandex/cloud/mdb/mysql/v1alpha/backup.proto";
import "yandex/cloud/mdb/mysql/v1alpha/cluster.proto";
import "yandex/cloud/mdb/mysql/v1alpha/database.proto";
import "yandex/cloud/mdb/mysql/v1alpha/user.proto";
import "yandex/cloud/mdb/mysql/v1alpha/config/mysql5_7.proto";

option go_package = "github.com/yandex-cloud/go-genproto/yandex/cloud/mdb/mysql/v1alpha;mysql";
option java_package = "yandex.cloud.api.mdb.mysql.v1alpha";

// A set of methods for managing MySQL clusters.
service ClusterService {
  // Returns the specified MySQL cluster.
  //
  // To get the list of available MySQL clusters, make a [List] request.
  rpc Get (GetClusterRequest) returns (Cluster) {
    option (google.api.http) = { get: "/managed-mysql/v1alpha/clusters/{cluster_id}" };
  }

  // Retrieves the list of MySQL clusters that belong to the specified folder.
  rpc List (ListClustersRequest) returns (ListClustersResponse) {
    option (google.api.http) = { get: "/managed-mysql/v1alpha/clusters" };
  }

  // Creates a MySQL cluster in the specified folder.
  rpc Create (CreateClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "CreateClusterMetadata"
      response: "Cluster"
    };
  }

  // Modifies the specified MySQL cluster.
  rpc Update (UpdateClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { patch: "/managed-mysql/v1alpha/clusters/{cluster_id}" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "UpdateClusterMetadata"
      response: "Cluster"
    };
  }

  // Deletes the specified MySQL cluster.
  rpc Delete (DeleteClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { delete: "/managed-mysql/v1alpha/clusters/{cluster_id}" };
    option (yandex.cloud.api.operation) = {
      metadata: "DeleteClusterMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Starts the specified MySQL cluster.
  rpc Start (StartClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters/{cluster_id}:start" };
    option (yandex.cloud.api.operation) = {
      metadata: "StartClusterMetadata"
      response: "Cluster"
    };
  }

  // Stops the specified MySQL cluster.
  rpc Stop (StopClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters/{cluster_id}:stop" };
    option (yandex.cloud.api.operation) = {
      metadata: "StopClusterMetadata"
      response: "Cluster"
    };
  }

  // Creates a backup for the specified MySQL cluster.
  rpc Backup (BackupClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters/{cluster_id}:backup" };
    option (yandex.cloud.api.operation) = {
      metadata: "BackupClusterMetadata"
      response: "Cluster"
    };
  }

  // Creates a new MySQL cluster using the specified backup.
  rpc Restore (RestoreClusterRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters:restore" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "RestoreClusterMetadata"
      response: "Cluster"
    };
  }

  // Retrieves logs for the specified MySQL cluster.
  rpc ListLogs (ListClusterLogsRequest) returns (ListClusterLogsResponse) {
    option (google.api.http) = { get: "/managed-mysql/v1alpha/clusters/{cluster_id}:logs" };
  }

  // Retrieves the list of operations for the specified MySQL cluster.
  rpc ListOperations (ListClusterOperationsRequest) returns (ListClusterOperationsResponse) {
    option (google.api.http) = { get: "/managed-mysql/v1alpha/clusters/{cluster_id}/operations" };
  }

  // Retrieves the list of available backups for the specified MySQL cluster.
  rpc ListBackups (ListClusterBackupsRequest) returns (ListClusterBackupsResponse) {
    option (google.api.http) = { get: "/managed-mysql/v1alpha/clusters/{cluster_id}/backups" };
  }

  // Retrieves a list of hosts for the specified MySQL cluster.
  rpc ListHosts (ListClusterHostsRequest) returns (ListClusterHostsResponse) {
    option (google.api.http) = { get: "/managed-mysql/v1alpha/clusters/{cluster_id}/hosts" };
  }

  // Creates new hosts for a cluster.
  rpc AddHosts (AddClusterHostsRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters/{cluster_id}/hosts:batchCreate" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "AddClusterHostsMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Deletes the specified hosts for a cluster.
  rpc DeleteHosts (DeleteClusterHostsRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/managed-mysql/v1alpha/clusters/{cluster_id}/hosts:batchDelete" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "DeleteClusterHostsMetadata"
      response: "google.protobuf.Empty"
    };
  }
}


message GetClusterRequest {
  // ID of the MySQL cluster to return.
  // To get the cluster ID use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];
}

message ListClustersRequest {
  // ID of the folder to list MySQL clusters in.
  // To get the folder ID, use a [yandex.cloud.resourcemanager.v1.FolderService.List] request.
  string folder_id = 1 [(required) = true, (length) = "<=50"];

  // The maximum number of results per page to return. If the number of available
  // results is larger than [page_size], the service returns a [ListClustersResponse.next_page_token]
  // that can be used to get the next page of results in subsequent list requests.
  int64 page_size = 2 [(value) = "0-1000"];

  // Page token. To get the next page of results, set [page_token] to the [ListClustersResponse.next_page_token]
  // returned by a previous list request.
  string page_token = 3 [(length) = "<=100"];

  // A filter expression that filters resources listed in the response.
  // The expression must specify:
  // 1. The field name. Currently you can only use filtering with the [Cluster.name] field.
  // 2. An operator. Can be either `=` or `!=` for single values, `IN` or `NOT IN` for lists of values.
  // 3. The value. Must be 1-63 characters long and match the regular expression `^[a-zA-Z0-9_-]+$`.
  string filter = 4 [(length) = "<=1000"];
}

message ListClustersResponse {
  // List of MySQL clusters.
  repeated Cluster clusters = 1;

  // This token allows you to get the next page of results for list requests. If the number of results
  // is larger than [ListClustersRequest.page_size], use the [next_page_token] as the value
  // for the [ListClustersRequest.page_token] parameter in the next list request. Each subsequent
  // list request will have its own [next_page_token] to continue paging through the results.
  string next_page_token = 2;
}

message CreateClusterRequest {
  // ID of the folder to create the MySQL cluster in.
  string folder_id = 1 [(required) = true, (length) = "<=50"];

  // Name of the MySQL cluster. The name must be unique within the folder.
  string name = 2 [(required) = true, (length) = "<=63", (pattern) = "[a-zA-Z0-9_-]*"];

  // Description of the MySQL cluster.
  string description = 3 [(length) = "<=256"];

  // Custom labels for the MySQL cluster as `key:value` pairs. Maximum 64 per resource.
  // For example, "project": "mvp" or "source": "dictionary".
  map<string, string> labels = 4 [(yandex.cloud.size) = "<=64", (length) = "<=63", (pattern) = "[-_0-9a-z]*", (map_key).length = "1-63", (map_key).pattern = "[a-z][-_0-9a-z]*"];

  // Deployment environment of the MySQL cluster.
  Cluster.Environment environment = 5;

  // Configuration and resources for hosts that should be created for the MySQL cluster.
  ConfigSpec config_spec = 6;

  // Descriptions of databases to be created in the MySQL cluster.
  repeated DatabaseSpec database_specs = 7;

  // Descriptions of database users to be created in the MySQL cluster.
  repeated UserSpec user_specs = 8;

  // Individual configurations for hosts that should be created for the MySQL cluster.
  repeated HostSpec host_specs = 9;

  // ID of the network to create the cluster in.
  string network_id = 10 [(length) = "<=50"];
}

message CreateClusterMetadata {
  // ID of the MySQL cluster that is being created.
  string cluster_id = 1;
}

message UpdateClusterRequest {
  // ID of the MySQL cluster to update.
  // To get the MySQL cluster ID, use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // Field mask that specifies which fields of the MySQL cluster should be updated.
  google.protobuf.FieldMask update_mask = 2;

  // New description of the MySQL cluster.
  string description = 3 [(length) = "<=256"];

  // Custom labels for the MySQL cluster as `key:value` pairs. Maximum 64 per resource.
  // For example, "project": "mvp" or "source": "dictionary".
  //
  // The new set of labels will completely replace the old ones. To add a label, request the current
  // set with the [ClusterService.Get] method, then send an [ClusterService.Update] request with the new label added to the set.
  map<string, string> labels = 4 [(yandex.cloud.size) = "<=64", (length) = "<=63", (pattern) = "[-_0-9a-z]*", (map_key).length = "1-63", (map_key).pattern = "[a-z][-_0-9a-z]*"];

  // New configuration and resources for hosts in the cluster.
  ConfigSpec config_spec = 5;

  // New name for the cluster.
  string name = 6 [(length) = "<=63", (pattern) = "[a-zA-Z0-9_-]*"];
}

message UpdateClusterMetadata {
  // ID of the MySQL cluster that is being modified.
  string cluster_id = 1;
}

message DeleteClusterRequest {
  // ID of the MySQL cluster to delete.
  // To get the MySQL cluster ID, use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];
}

message DeleteClusterMetadata {
  // ID of the MySQL cluster that is being deleted.
  string cluster_id = 1;
}

message BackupClusterRequest {
  // ID of the MySQL cluster to back up.
  // To get the MySQL cluster ID, use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];
}

message BackupClusterMetadata {
  // ID of the MySQL cluster that is being backed up.
  string cluster_id = 1;
}

message RestoreClusterRequest {
  // ID of the backup to create a cluster from.
  // To get the backup ID, use a [ClusterService.ListBackups] request.
  string backup_id = 1 [(required) = true];

  // Timestamp of the moment to which the MySQL cluster should be restored.
  google.protobuf.Timestamp time = 2 [(required) = true];

  // Name of the new MySQL cluster. The name must be unique within the folder.
  string name = 4 [(required) = true, (pattern) = "[a-zA-Z0-9_-]*"];

  // Description of the new MySQL cluster.
  string description = 5 [(length) = "<=256"];

  // Custom labels for the MySQL cluster as `key:value` pairs. Maximum 64 per resource.
  // For example, "project": "mvp" or "source": "dictionary".
  map<string, string> labels = 6 [(yandex.cloud.size) = "<=64", (length) = "<=63", (pattern) = "[-_0-9a-z]*", (map_key).length = "1-63", (map_key).pattern = "[a-z][-_0-9a-z]*"];

  // Deployment environment of the new MySQL cluster.
  Cluster.Environment environment = 7;

  // Configuration for the MySQL cluster to be created.
  ConfigSpec config_spec = 8;

  // Configurations for MySQL hosts that should be added
  // to the cluster that is being created from the backup.
  repeated HostSpec host_specs = 9;

  // ID of the network to create the MySQL cluster in.
  string network_id = 10 [(length) = "<=50"];
}

message RestoreClusterMetadata {
  // ID of the new MySQL cluster that is being created from a backup.
  string cluster_id = 1;

  // ID of the backup that is being used for creating a cluster.
  string backup_id = 2;
}

message LogRecord {
  // Log record timestamp in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format.
  google.protobuf.Timestamp timestamp = 1;

  // Contents of the log record.
  map<string, string> message = 2;
}

message ListClusterLogsRequest {
  // ID of the MySQL cluster to request logs for.
  // To get the MySQL cluster ID use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // Columns from the logs table to request.
  // If no columns are specified, entire log records are returned.
  repeated string column_filter = 2;

  // Type of the service to request logs about.
  ServiceType service_type = 3;

  enum ServiceType {
    SERVICE_TYPE_UNSPECIFIED = 0;

    // Logs of MySQL activity.
    MYSQL = 1;
  }

  // Start timestamp for the logs request.
  google.protobuf.Timestamp from_time = 4;

  // End timestamp for the logs request.
  google.protobuf.Timestamp to_time = 5;

  // The maximum number of results per page to return. If the number of available
  // results is larger than [page_size], the service returns a [ListClusterLogsResponse.next_page_token]
  // that can be used to get the next page of results in subsequent list requests.
  int64 page_size = 6 [(value) = "0-1000"];

  // Page token. To get the next page of results, set [page_token] to the
  // [ListClusterLogsResponse.next_page_token] returned by a previous list request.
  string page_token = 7 [(length) = "<=100"];

  // Always return `next_page_token`, even if current page is empty.
  bool always_next_page_token = 8;
}

message ListClusterLogsResponse {
  // Requested log records.
  repeated LogRecord logs = 1;

  // This token allows you to get the next page of results for list requests. If the number of results
  // is larger than [ListClusterLogsRequest.page_size], use the [next_page_token] as the value
  // for the [ListClusterLogsRequest.page_token] query parameter in the next list request.
  // Each subsequent list request will have its own [next_page_token] to continue paging through the results.
  string next_page_token = 2;
}

message ListClusterOperationsRequest {
  // ID of the MySQL cluster to list operations for.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // The maximum number of results per page to return. If the number of available
  // results is larger than [page_size], the service returns a [ListClusterOperationsResponse.next_page_token]
  // that can be used to get the next page of results in subsequent list requests.
  int64 page_size = 2 [(value) = "0-1000"];

  // Page token.  To get the next page of results, set [page_token] to the [ListClusterOperationsResponse.next_page_token]
  // returned by a previous list request.
  string page_token = 3 [(length) = "<=100"];
}

message ListClusterOperationsResponse {
  // List of operations for the specified MySQL cluster.
  repeated operation.Operation operations = 1;

  // This token allows you to get the next page of results for list requests. If the number of results
  // is larger than [ListClusterOperationsRequest.page_size], use the [next_page_token] as the value
  // for the [ListClusterOperationsRequest.page_token] query parameter in the next list request.
  // Each subsequent list request will have its own [next_page_token] to continue paging through the results.
  string next_page_token = 2;
}

message ListClusterBackupsRequest {
  // ID of the MySQL cluster.
  // To get the MySQL cluster ID use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // The maximum number of results per page to return. If the number of available
  // results is larger than [page_size], the service returns a [ListClusterBackupsResponse.next_page_token]
  // that can be used to get the next page of results in subsequent list requests.
  int64 page_size = 2 [(value) = "<=1000"];

  // Page token.  To get the next page of results, set [page_token] to the [ListClusterBackupsResponse.next_page_token]
  // returned by a previous list request.
  string page_token = 3 [(length) = "<=100"];
}

message ListClusterBackupsResponse {
  // List of MySQL backups.
  repeated Backup backups = 1;

  // This token allows you to get the next page of results for list requests. If the number of results
  // is larger than [ListClusterBackupsRequest.page_size], use the [next_page_token] as the value
  // for the [ListClusterBackupsRequest.page_token] query parameter in the next list request.
  // Each subsequent list request will have its own [next_page_token] to continue paging through the results.
  string next_page_token = 2;
}

message ListClusterHostsRequest {
  // ID of the MySQL cluster.
  // To get the MySQL cluster ID use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // The maximum number of results per page to return. If the number of available
  // results is larger than [page_size], the service returns a [ListClusterHostsResponse.next_page_token]
  // that can be used to get the next page of results in subsequent list requests.
  int64 page_size = 2 [(value) = "0-1000"];

  // Page token.  To get the next page of results, set [page_token] to the [ListClusterHostsResponse.next_page_token]
  // returned by a previous list request.
  string page_token = 3 [(length) = "<=100"];
}

message ListClusterHostsResponse {
  // List of MySQL hosts.
  repeated Host hosts = 1;

  // This token allows you to get the next page of results for list requests. If the number of results
  // is larger than [ListClusterHostsRequest.page_size], use the [next_page_token] as the value
  // for the [ListClusterHostsRequest.page_token] query parameter in the next list request.
  // Each subsequent list request will have its own [next_page_token] to continue paging through the results.
  string next_page_token = 2;
}

message AddClusterHostsRequest {
  // ID of the MySQL cluster to add hosts to.
  // To get the MySQL cluster ID, use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // Configurations for MySQL hosts that should be added to the cluster.
  repeated HostSpec host_specs = 2 [(size) = ">0"];
}

message AddClusterHostsMetadata {
  // ID of the MySQL cluster to which the hosts are being added.
  string cluster_id = 1;

  // Names of hosts that are being added to the cluster.
  repeated string host_names = 2;
}

message DeleteClusterHostsRequest {
  // ID of the MySQL cluster to remove hosts from.
  // To get the MySQL cluster ID, use a [ClusterService.List] request.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];

  // Names of hosts to delete.
  repeated string host_names = 2 [(size) = ">0", (length) = "<=253"];
}

message DeleteClusterHostsMetadata {
  // ID of the MySQL cluster to remove hosts from.
  string cluster_id = 1;

  // Names of hosts that are being deleted.
  repeated string host_names = 2;
}

message StartClusterRequest {
  // ID of the MySQL cluster to start.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];
}

message StartClusterMetadata {
  // ID of the MySQL cluster being started.
  string cluster_id = 1;
}

message StopClusterRequest {
  // ID of the MySQL cluster to stop.
  string cluster_id = 1 [(required) = true, (length) = "<=50"];
}

message StopClusterMetadata {
  // ID of the MySQL cluster being stopped.
  string cluster_id = 1;
}

message UpdateClusterHostsMetadata {
  // ID of the MySQL cluster to modify hosts in.
  string cluster_id = 1;

  // Names of hosts that are being modified.
  repeated string host_names = 2;
}

message HostSpec {
  // ID of the availability zone where the host resides.
  // To get a list of available zones, use the [yandex.cloud.compute.v1.ZoneService.List] request.
  string zone_id = 1 [(length) = "<=50"];

  // ID of the subnet that the host should belong to. This subnet should be a part
  // of the network that the cluster belongs to.
  // The ID of the network is set in the field [Cluster.network_id].
  string subnet_id = 2 [(length) = "<=50"];

  // Whether the host should get a public IP address on creation.
  //
  // After a host has been created, this setting cannot be changed. To remove an assigned public IP, or to assign
  // a public IP to a host without one, recreate the host with [assign_public_ip] set as needed.
  //
  // Possible values:
  // * false - don't assign a public IP to the host.
  // * true - the host should have a public IP address.
  bool assign_public_ip = 3;
}

message ConfigSpec {
  // Version of MySQL used in the cluster.
  // Possible values:
  // * 5.7
  string version = 1; // No formal validation, a list of supported versions should suffice.

  // Configuration of a MySQL cluster.
  oneof mysql_config {
    // Configuration for a MySQL 5.7 cluster.
    config.MysqlConfig5_7 mysql_config_5_7 = 2 [json_name="mysqlConfig_5_7"];
  }

  // Resources allocated to MySQL hosts.
  Resources resources = 3;

  // Time to start the daily backup, in the UTC timezone.
  google.type.TimeOfDay backup_window_start = 4;
}
