syntax = "proto3";

package yandex.cloud.apploadbalancer.v1;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "yandex/cloud/apploadbalancer/v1/payload.proto";
import "yandex/cloud/apploadbalancer/v1/tls.proto";
import "yandex/cloud/validation.proto";

option go_package = "github.com/yandex-cloud/go-genproto/yandex/cloud/apploadbalancer/v1;apploadbalancer";
option java_package = "yandex.cloud.api.apploadbalancer.v1";

// A backend group resource.
// For details about the concept, see [documentation](/docs/application-load-balancer/concepts/backend-group).
message BackendGroup {
  // ID of the backend group. Generated at creation time.
  string id = 1;

  // Name of the backend group. The name is unique within the folder. The string length in characters is 3-63.
  string name = 2;

  // Description of the backend group. The string is 0-256 characters long.
  string description = 3;

  // ID of the folder that the backend group belongs to.
  string folder_id = 4;

  // Backend group labels as `key:value` pairs.
  // For details about the concept, see [documentation](/docs/overview/concepts/services#labels).
  // The maximum number of labels is 64.
  map<string, string> labels = 5;

  // Backends that the backend group consists of.
  //
  // A backend group must consist of either HTTP backends or gRPC backends.
  oneof backend {
    // List of HTTP backends that the backend group consists of.
    HttpBackendGroup http = 6;

    // List of gRPC backends that the backend group consists of.
    GrpcBackendGroup grpc = 7;
  }

  // Creation timestamp.
  google.protobuf.Timestamp created_at = 9;
}

// An HTTP backend group resource.
message HttpBackendGroup {
  // List of HTTP backends.
  repeated HttpBackend backends = 1;
}

// A gRPC backend group resource.
message GrpcBackendGroup {
  // List of gRPC backends.
  repeated GrpcBackend backends = 1;
}

message HeaderSessionAffinity {
  string header_name = 1 [(length) = "1-256"];
}

message CookieSessionAffinity {
  string name = 1 [(length) = "1-256"];
  // If not set, session cookie will be used (not persisted between browser restarts).
  google.protobuf.Duration ttl = 2;
}

message ConnectionSessionAffinity {
  bool source_ip = 1;
}

// A load balancing configuration resource.
message LoadBalancingConfig {
  // Threshold for panic mode.
  //
  // If percentage of healthy backends in the group drops below threshold,
  // panic mode will be activated and traffic will be routed to all backends, regardless of their health check status.
  // This helps to avoid overloading healthy backends.
  // For details about panic mode, see [documentation](/docs/application-load-balancer/concepts/backend-group#panic-mode).
  //
  // If the value is `0`, panic mode will never be activated and traffic is routed only to healthy backends at all times.
  //
  // Default value: `0`.
  int64 panic_threshold = 1 [(value) = "0-100"];

  // Percentage of traffic that a load balancer node sends to healthy backends in its availability zone.
  // The rest is divided equally between other zones. For details about zone-aware routing, see [documentation](/docs/application-load-balancer/concepts/backend-group#locality).
  //
  // If there are no healthy backends in an availability zone, all the traffic is divided between other zones.
  //
  // If [strict_locality] is `true`, the specified value is ignored.
  // A load balancer node sends all the traffic within its availability zone, regardless of backends' health.
  //
  // Default value: `0`.
  int64 locality_aware_routing_percent = 2 [(value) = "0-100"];

  // Specifies whether a load balancer node should only send traffic to backends in its availability zone,
  // regardless of their health, and ignore backends in other zones.
  //
  // If set to `true` and there are no healthy backends in the zone, the node in this zone will respond
  // to incoming traffic with errors.
  // For details about strict locality, see [documentation](/docs/application-load-balancer/concepts/backend-group#locality).
  //
  // If `strict_locality` is `true`, the value specified in [locality_aware_routing_percent] is ignored.
  //
  // Default value: `false`.
  bool strict_locality = 3;
}

// An HTTP backend resource.
message HttpBackend {
  // Name of the backend.
  string name = 1 [(required) = true, (pattern) = "[a-z][-a-z0-9]{1,61}[a-z0-9]"];

  // Backend weight. Traffic is distributed between backends of a backend group according to their weights.
  //
  // Weights must be set either for all backends in a group or for none of them.
  // Setting no weights is the same as setting equal non-zero weights for all backends.
  //
  // If the weight is non-positive, traffic is not sent to the backend.
  google.protobuf.Int64Value backend_weight = 2;

  // Load balancing configuration for the backend.
  LoadBalancingConfig load_balancing_config = 3;

  // Port used by all targets to receive traffic.
  int64 port = 4 [(value) = "0-65535"];

  // Reference to targets that belong to the backend.
  //
  // A backend may be a set of target groups or an Object Storage bucket. For details about backend types, see
  // [documentation](/docs/application-load-balancer/concepts/backend-group#types).
  oneof backend_type {
    option (exactly_one) = true;

    // Target groups that belong to the backend. For details about target groups, see
    // [documentation](/docs/application-load-balancer/concepts/target-group).
    TargetGroupsBackend target_groups = 5;

    // Object Storage bucket to use as the backend. For details about buckets, see
    // [documentation](/docs/storage/concepts/bucket).
    //
    // If a bucket is used as a backend, the list of bucket objects and the objects themselves must be publicly
    // accessible. For instructions, see [documentation](/docs/storage/operations/buckets/bucket-availability).
    StorageBucketBackend storage_bucket = 9;
  }

  // Health checks to perform on targets from target groups.
  // For details about health checking, see [documentation](/docs/application-load-balancer/concepts/backend-group#health-checks).
  //
  // If no health checks are specified, active health checking is not performed.
  repeated HealthCheck healthchecks = 6;

  // Settings for TLS connections between load balancer nodes and backend targets.
  //
  // If specified, the load balancer establishes HTTPS (HTTP over TLS) connections with targets
  // and compares received certificates with the one specified in [BackendTls.validation_context].
  // If not specified, the load balancer establishes unencrypted HTTP connections with targets.
  BackendTls tls = 7;

  // Enables HTTP/2 usage in connections between load balancer nodes and backend targets.
  //
  // Default value: `false`, HTTP/1.1 is used.
  bool use_http2 = 8;
}

// A gRPC backend resource.
message GrpcBackend {
  // Name of the backend.
  string name = 1 [(required) = true, (pattern) = "[a-z][-a-z0-9]{1,61}[a-z0-9]"];

  // Backend weight. Traffic is distributed between backends of a backend group according to their weights.
  //
  // Weights must be set either for all backends of a group or for none of them.
  // Setting no weights is the same as setting equal non-zero weights for all backends.
  //
  // If the weight is non-positive, traffic is not sent to the backend.
  google.protobuf.Int64Value backend_weight = 2;

  // Load balancing configuration for the backend.
  LoadBalancingConfig load_balancing_config = 3;

  // Port used by all targets to receive traffic.
  int64 port = 4 [(value) = "0-65535"];

  // Reference to targets that belong to the backend. For now, targets are referenced via target groups.
  oneof backend_type {
    option (exactly_one) = true;

    // Target groups that belong to the backend.
    TargetGroupsBackend target_groups = 5;
  }

  // Health checks to perform on targets from target groups.
  // For details about health checking, see [documentation](/docs/application-load-balancer/concepts/backend-group#health-checks).
  //
  // If no health checks are specified, active health checking is not performed.
  repeated HealthCheck healthchecks = 7;

  // Settings for TLS connections between load balancer nodes and backend targets.
  //
  // If specified, the load balancer establishes HTTPS (HTTP over TLS) connections with targets
  // and compares received certificates with the one specified in [BackendTls.validation_context].
  // If not specified, the load balancer establishes unencrypted HTTP connections with targets.
  BackendTls tls = 8;
}

// A resource for target groups that belong to the backend.
message TargetGroupsBackend {
  // List of ID's of target groups that belong to the backend.
  //
  // To get the ID's of all available target groups, make a [TargetGroupService.List] request.
  repeated string target_group_ids = 1 [(size)=">0"];
}

// A resource for backend TLS settings.
message BackendTls {
  // Server Name Indication (SNI) string for TLS connections.
  string sni = 1;

  // Validation context for TLS connections.
  ValidationContext validation_context = 3;
}

// A resource for Object Storage bucket used as a backend. For details about the concept,
// see [documentation](/docs/storage/concepts/bucket).
message StorageBucketBackend {
  // Name of the bucket.
  string bucket = 1 [(required) = true];
}

// A health check resource.
// For details about the concept, see [documentation](/docs/application-load-balancer/concepts/backend-group#health-checks).
message HealthCheck {
  // Health check timeout.
  //
  // The timeout is the time allowed for the target to respond to a check.
  // If the target doesn't respond in time, the check is considered failed.
  google.protobuf.Duration timeout = 1 [(required) = true];

  // Base interval between consecutive health checks.
  google.protobuf.Duration interval = 2 [(required) = true];

  double interval_jitter_percent = 3;

  // Number of consecutive successful health checks required to mark an unhealthy target as healthy.
  //
  // Both `0` and `1` values amount to one successful check required.
  //
  // The value is ignored when a load balancer is initialized; a target is marked healthy after one successful check.
  //
  // Default value: `0`.
  int64 healthy_threshold = 4;

  // Number of consecutive failed health checks required to mark a healthy target as unhealthy.
  //
  // Both `0` and `1` values amount to one unsuccessful check required.
  //
  // The value is ignored if a health check is failed due to an HTTP `503 Service Unavailable` response from the target
  // (not applicable to TCP stream health checks). The target is immediately marked unhealthy.
  //
  // Default value: `0`.
  int64 unhealthy_threshold = 5;

  // Port used for health checks.
  //
  // If not specified, the backend port ([HttpBackend.port] or [GrpcBackend.port]) is used for health checks.
  int64 healthcheck_port = 6 [(value) = "0-65535"];

  // A resource for TCP stream health check settings.
  message StreamHealthCheck {
    // Message sent to targets during TCP data transfer.
    //
    // If not specified, no data is sent to the target.
    Payload send = 1;

    // Data that must be contained in the messages received from targets for a successful health check.
    //
    // If not specified, no messages are expected from targets, and those that are received are not checked.
    Payload receive = 2;
  }

  // A resource for HTTP health check settings.
  message HttpHealthCheck {
    // Value for the HTTP/1.1 `Host` header or the HTTP/2 `:authority` pseudo-header used in requests to targets.
    string host = 1;

    // HTTP path used in requests to targets: request URI for HTTP/1.1 request line
    // or value for the HTTP/2 `:path` pseudo-header.
    string path = 2 [(required) = true];

    // Enables HTTP/2 usage in health checks.
    //
    // Default value: `false`, HTTP/1.1 is used.
    bool use_http2 = 3;
  }

  // A resource for gRPC health check settings.
  message GrpcHealthCheck {
    // Name of the gRPC service to be checked.
    //
    // If not specified, overall health is checked.
    //
    // For details about the concept, see [GRPC Health Checking Protocol](https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
    string service_name = 1;
  }

  // Protocol-specific health check settings.
  //
  // The protocols of the backend and of its health check may differ,
  // e.g. a gRPC health check may be specified for an HTTP backend.
  oneof healthcheck {
    option (exactly_one) = true;
    // TCP stream health check settings.
    StreamHealthCheck stream = 7;
    // HTTP health check settings.
    HttpHealthCheck http = 8;
    // gRPC health check settings.
    GrpcHealthCheck grpc = 9;
  }
}
