syntax = "proto3";

package cluster;

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
// import "github.com/gogo/protobuf/gogoproto/gogo.proto";
// import "github.com/mwitkow/go-proto-validators/validator.proto";

option go_package = "pkg/service/cluster/;cluster";

service ClusterService {
    rpc Profiles (ProfileReq) returns (Profile) {
        option (google.api.http) = {
            get: "/api/v1/cluster_profiles/{provider}/profiles"
        };
    }

    rpc Get (ClusterGetReq) returns (Cluster) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{id}"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "GetCluster"
        };
    }

    rpc GetDeletedCluster (ClusterIdReq) returns (DeletedCluster) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/recycle-bin/{cluster_id}"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "GetDeletedCluster"
        };
    }

    rpc GetTiDBNodes (TiDBNodesReq) returns (TiDBNodes) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/tidb_nodes"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "GetTiDBNodes"
        };
    }

    rpc GetTiKVNodes (TiKVNodesReq) returns (TiKVNodes) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/tikv_nodes"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "GetTiKVNodes"
        };
    }

    rpc GetTiFlashNodes (TiFlashNodesReq) returns (TiFlashNodes) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/tiflash_nodes"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "GetTiFlashNodes"
        };
    }

    rpc List (ClusterListReq) returns (Clusters) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "ListClusters"
        };
    }

    rpc ListDeletedClusters (ClusterListReq) returns (DeletedClusters) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/recycle-bin"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "ListDeletedClusters"
        };
    }

    rpc Create (ClusterCreateReq) returns (ClusterId) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "CreateCluster"
        };
    }

    rpc Delete (ClusterIdReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "DeleteCluster"
        };
    }

    rpc ChangePassword (ChangePasswordReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/password"
            body: "*"
        };
    }

    rpc SendPasswordVerifyCode (SendPasswordVerifyCodeReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/password-verify-code"
            body: "*"
        };
    }

    rpc ChangeClusterName (ChangeClusterNameReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            patch: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}"
            body: "*"
        };
    }

    rpc ScaleComponent (ScaleComponentReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/components"
            body: "*"
        };
    }

    rpc CreateAWSVpcPeering (CreateAWSVpcPeeringReq) returns (CreateAWSVpcPeeringResp) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/aws_vpc_peerings"
            body: "*"
        };
    }

    rpc CreateGcpVpcPeering (CreateGcpVpcPeeringReq) returns (CreateAGcpVpcPeeringResp) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/gcp_vpc_peerings"
            body: "*"
        };
    }

    rpc ListAwsVpcPeerings (ProjectIdReq) returns (AwsVpcPeerings) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/aws_vpc_peerings"
        };
    }

    rpc ListGcpVpcPeerings (ProjectIdReq) returns (GcpVpcPeerings) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/gcp_vpc_peerings"
        };
    }

    rpc GetAwsVpcPeering (RegionNameAndProjectId) returns (AwsVpcPeering) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/aws_vpc_peerings/{name}"
        };
    }

    rpc GetGcpVpcPeering (RegionNameAndProjectId) returns (GcpVpcPeering) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/gcp_vpc_peerings/{name}"
        };
    }

    rpc DeleteAwsVpcPeering (RegionNameAndProjectId) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/orgs/{org_id}/projects/{project_id}/aws_vpc_peerings/{name}"
        };
    }

    rpc DeleteGcpVpcPeering (RegionNameAndProjectId) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/orgs/{org_id}/projects/{project_id}/gcp_vpc_peerings/{name}"
        };
    }

    rpc CreatePrivateEndpoint (ClusterIdReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/connections"
        };
    }

    rpc GetTrafficFilter (ClusterIdReq) returns (TrafficFilterResp) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/traffic_filter"
        };
    }

    rpc UpdateTrafficFilter (UpdateTrafficFilterReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/traffic_filter"
            body: "*"
        };
    }

    rpc GetPrivateEndpoint (ClusterIdReq) returns (GetPrivateEndpointResp) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/clusters/{cluster_id}/connections"
        };
    }
}

message Profile {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["provider", "instances", "regions", "global_discount"]
        }
    };

    string provider = 1;
    repeated Instance instances = 2;
    repeated Region regions = 3;
    double global_discount = 4;
}

message ProfileReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["provider"]
        }
    };

    string provider = 1;
}

enum VerifyCodeUsage {
    VERIFYCODE_UNKNOWN = 0;
    PASSWORD = 1;
}

message ChangePasswordReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cluster_id", "password", "verify_code", "org_id", "project_id"]
        }
    };

    uint64 cluster_id = 1;
    string password = 2;
    string verify_code = 3;
	uint64 org_id = 4;
    uint64 project_id = 5;
}

message SendPasswordVerifyCodeReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cluster_id", "org_id", "project_id"]
        }
    };

	uint64 cluster_id = 1;
	uint64 org_id = 2;
    uint64 project_id = 3;
}

message ChangeClusterNameReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cluster_id", "cluster_name", "org_id", "project_id"]
        }
    };

    uint64 cluster_id = 1;
    string cluster_name = 2;
	uint64 org_id = 3;
    uint64 project_id = 4;
}

message ClusterListReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["page", "per_page", "provider", "org_id", "project_id"]
        }
    };

    uint32 page = 1;
    uint32 per_page = 2;
    string provider = 3;
	uint64 org_id = 4;
    uint64 project_id = 5;
}

message ClusterGetReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "org_id", "project_id"]
        }
    };

	uint64 id = 1;
	uint64 org_id = 2;
    uint64 project_id = 3;
}

message ClusterCreateReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "name", "root_password", "provider", "region", "profile_name", "tikv_count", "tidb_count", "tiflash_count", "project_id"]
        }
    };

    uint64 org_id = 1;
    string name = 2;
    string root_password = 3;
    string provider = 4;
    string region = 5;
    string profile_name = 6;
    uint32 tikv_count = 7;
    uint32 tidb_count = 8;
    uint32 tiflash_count = 9;
    uint64 project_id = 10;
}

message ClusterId {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id"]
        }
    };

    uint64 id = 1;
}

message ClusterIdReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id", "cluster_id"]
        }
    };

	uint64 org_id = 1;
    uint64 project_id = 2;
    uint64 cluster_id = 3;
}


message TenantIdReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["tenant_id"]
        }
    };

    uint64 tenant_id = 1;
}

enum InfraErrorCode {
    INFRA_RESOURCES_DEPLETED = 0;
}

message LastError {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["codes"]
        }
    };

    repeated InfraErrorCode codes = 1;
}

message Cluster {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "name", "status", "secondary_status", "version", "provider", "region", "profile_name", "created_at", "created_by", "endpoint", "vpc_cidr_block", "capacity", "cluster_components", "create_progress", "prometheus_ready", "privateEndpoint", "restored", "role_arn", "import_id", "lastErrors"]
        }
    };

    int64 id = 1;
    string name = 2;
    enum Status {
        NORMAL = 0;
        CREATING = 1;
        SCALING = 2;
        UPGRADING = 3;
        UNAVAILABLE = 4;
        RECOVERING = 5;
        IMPORTING = 6;
    }
    Status status = 3;
    enum SecondaryStatus {
        HEALTHY = 0;
        UNHEALTHY = 1;
    }
    SecondaryStatus secondary_status = 4;
    string version = 5;
    string provider = 6;
    string region = 7;
    string profile_name = 8;
    google.protobuf.Timestamp created_at = 9;
    User created_by = 10;
    Endpoint endpoint = 11;
    string vpc_cidr_block = 12;
    uint32 capacity = 13;
    ClusterComponents cluster_components = 14;
    enum CreateProgress {
        INITIALIZING = 0;
        PREPARING = 1;
        LAUNCHING = 2;
        COMPLETED = 3;
    }
    CreateProgress create_progress = 15;
    bool prometheus_ready = 16;
    Endpoint privateEndpoint = 17;
    bool restored = 18;

    // only set when status is IMPORTING
    string role_arn = 19;
    uint64 import_id = 20;
    repeated LastError lastErrors = 21;
}

message Clusters {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated Cluster items = 2;
}

message DeletedClusters {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated DeletedCluster items = 2;
}

message ClusterComponents {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["tikv", "tidb", "tiflash"]
        }
    };

    Component tikv = 1;
    Component tidb = 2;
    Component tiflash = 3;
}

message Component {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["replicas", "node_profile"]
        }
    };

    uint32 replicas = 1;
    NodeProfile node_profile = 2;
}

message NodeProfile {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["compute", "storage_gi"]
        }
    };

    Compute compute = 1;
    uint32 storage_gi = 2;
}

message Endpoint {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["ready", "address", "port"]
        }
    };

    bool ready = 1;
    string address = 2;
    int32 port = 3;
}

message Compute {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cpu", "memory_mi"]
        }
    };

    float cpu = 1;
    uint32 memory_mi = 2;
}

message ComponentScale {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["component_name", "replicas"]
        }
    };

    string component_name = 1;
    uint32 replicas = 2;
}

message ScaleComponentReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cluster_id", "components", "org_id", "project_id"]
        }
    };

    uint64 cluster_id = 1;
    repeated ComponentScale components = 2;
	uint64 org_id = 3;
    uint64 project_id = 4;
}

message TiKVNode {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["name", "status", "az", "compute", "storage_gi", "type"]
        }
    };

    string name = 1;
    enum Status {
        NORMAL = 0;
        CREATING = 1;
        UNAVAILABLE = 2;
        TERMINATING = 3;
        LEAVING = 4;
    }
    Status status = 2;
    string az = 3;
    Compute compute = 4;
    uint32 storage_gi = 5;
    enum Type {
        STORAGE = 0;
    }
    Type type = 6;
}

message TiFlashNode {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["name", "status", "az", "compute", "storage_gi", "type"]
        }
    };

    string name = 1;
    enum Status {
        NORMAL = 0;
        CREATING = 1;
        UNAVAILABLE = 2;
        TERMINATING = 3;
        LEAVING = 4;
    }
    Status status = 2;
    string az = 3;
    Compute compute = 4;
    uint32 storage_gi = 5;
    enum Type {
        STORAGE = 0;
    }
    Type type = 6;
}

message TiDBNode {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["name", "status", "az", "compute", "type"]
        }
    };

    string name = 1;
    enum Status {
        NORMAL = 0;
        CREATING = 1;
        UNAVAILABLE = 2;
        TERMINATING = 3;
    }
    Status status = 2;
    string az = 3;
    Compute compute = 4;
    enum Type {
        COMPUTING = 0;
    }
    Type type = 5;
}

message TiDBNodesReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["page", "per_page", "cluster_id", "org_id", "project_id"]
        }
    };

    uint32 page = 1;
    uint32 per_page = 2;
    uint64 cluster_id = 3;
	uint64 org_id = 4;
    uint64 project_id = 5;
}

message TiDBNodes {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated TiDBNode items = 2;
}

message TiKVNodesReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["page", "per_page", "cluster_id", "org_id", "project_id"]
        }
    };

    uint32 page = 1;
    uint32 per_page = 2;
    uint64 cluster_id = 3;
	uint64 org_id = 4;
    uint64 project_id = 5;
}

message TiFlashNodesReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["page", "per_page", "cluster_id", "org_id", "project_id"]
        }
    };

    uint32 page = 1;
    uint32 per_page = 2;
    uint64 cluster_id = 3;
	uint64 org_id = 4;
    uint64 project_id = 5;
}

message TiKVNodes {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated TiKVNode items = 2;
}

message TiFlashNodes {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated TiFlashNode items = 2;
}


message CreateAWSVpcPeeringReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["tenant_region", "tenant_vpc_id", "tenant_account_id", "tenant_vpc_cidr", "region", "org_id", "project_id"]
        }
    };

    string tenant_region = 1;
    string tenant_vpc_id = 2;
    string tenant_account_id = 3;
    string tenant_vpc_cidr = 4;
    string region = 5;
    uint64 org_id = 6;
    uint64 project_id = 7;
}

message CreateAWSVpcPeeringResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["vpc_peering_id", "vpc_cidr", "private_host_zone", "region"]
        }
    };

    string vpc_peering_id = 1;
    string vpc_cidr = 2;
    string private_host_zone = 3;
    string region = 4;
}

message CreateGcpVpcPeeringReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["tenant_project_id", "tenant_vpc_region", "tenant_network_name", "region", "org_id", "project_id"]
        }
    };

    string tenant_project_id = 1;
    string tenant_vpc_region = 2;
    string tenant_network_name = 3;
    string region = 4;
    uint64 org_id = 5;
    uint64 project_id = 6;
}

message CreateAGcpVpcPeeringResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["project_id", "network_name", "region"]
        }
    };

    string project_id = 1;
    string network_name = 2;
    string region = 4;
}

message GcpVpcPeering {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["region", "network_name", "project_id", "tenant_project_id", "tenant_network_name", "status"]
        }
    };

    string region = 1;
    string network_name = 2;
    string project_id = 3;

    string tenant_project_id = 4;
    string tenant_network_name = 5;
    string status = 6;
}

message AwsVpcPeering {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["region", "private_host_zone", "vpc_peering_id", "vpc_cidr", "tenant_vpc_cidr", "tenant_vpc_id", "status"]
        }
    };

    string region = 1;
    string private_host_zone = 2;
    string vpc_peering_id = 3;
    string vpc_cidr = 4;

    string tenant_vpc_cidr = 5;
    string tenant_vpc_id = 6;

    string status = 7;
}

message GcpVpcPeerings {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated GcpVpcPeering items = 2;
}

message AwsVpcPeerings {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated AwsVpcPeering items = 2;
}

message RegionNameAndProjectId {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["name", "org_id", "project_id"]
        }
    };

    string name = 1;
    uint64 org_id = 2;
    uint64 project_id = 3;
}

enum PrivateEndpointStatus {
    NO_VPC_PEERING = 0;
    VPC_PEERING_ERROR = 1;
    NO_DOMAIN = 2;
    CREATING = 3;
    NORMAL = 4;
}

message GetPrivateEndpointResp {
   option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
       json_schema: {
           required: ["status", "domain", "port"]
       }
   };

   PrivateEndpointStatus status = 1;
   string domain = 2;
   uint64 port = 3;
}

// Common

message TrafficFilter {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cidr", "description"]
        }
    };

    string cidr = 1;
    string description = 2;
}

message TrafficFilterList {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cidrs"]
        }
    };

    repeated TrafficFilter cidrs = 1;
}

message TrafficFilterResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "traffic_filters"]
        }
    };

    int32 total = 1;
    TrafficFilterList traffic_filters = 2;
}

message ProjectIdReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
}

message UpdateTrafficFilterReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["traffic_filters", "cluster_id", "org_id", "project_id"]
        }
    };

    TrafficFilterList traffic_filters = 1;
    int64 cluster_id = 2;
	uint64 org_id = 3;
    uint64 project_id = 4;
}

message Instance {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["profile_name", "description", "available_regions", "tidb", "tikv", "tiflash"]
        }
    };

    string profile_name = 1;
    string description = 2;
    repeated AvailableRegion available_regions = 3;
    Machine tidb = 4;
    Machine tikv = 5;
    Machine tiflash = 6;
}

message Machine {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["component_name", "replicas", "cpu", "memory_gi", "disks"]
        }
    };

    string component_name = 1;
    uint32 replicas = 2;
    uint32 cpu = 3;
    uint32 memory_gi = 4;
    repeated Disk disks = 5;
}

message Disk {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["disk_gi"]
        }
    };

    uint32 disk_gi = 1;
}

message Region {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["name", "display_name"]
        }
    };

    string name = 1;
    string display_name = 2;
}

message User {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "email", "name", "status", "invite_time", "role"]
        }
    };

    uint64 id = 1;
    string email = 2;
    string name = 3;
    string status = 4;
    google.protobuf.Timestamp invite_time = 5;
    string role = 6;
}

message AvailableRegion {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["region_name", "price"]
        }
    };

    string region_name = 1;
    Price price = 2;
}

message Price {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["tidb", "tikv", "tiflash"]
        }
    };

    double tidb = 1;
    double tikv = 2;
    double tiflash = 3;
}

message DeletedCluster {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "name", "provider", "region", "profile_name", "delete_time", "latest_backup_size"]
        }
    };

    uint64 id = 1;
    string name = 2;
    string provider = 3;
    string region = 4;
    string profile_name = 5;
    google.protobuf.Timestamp delete_time = 6;
    uint64 latest_backup_size = 7;
}
