syntax = "proto3";

package yandex.cloud.apploadbalancer.v1;

import "google/api/annotations.proto";
import "google/protobuf/field_mask.proto";

import "yandex/cloud/api/operation.proto";
import "yandex/cloud/operation/operation.proto";
import "yandex/cloud/apploadbalancer/v1/load_balancer.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 set of methods for managing application load balancers.
service LoadBalancerService {
  // Returns the specified application load balancer.
  //
  // To get the list of all available application load balancers, make a [List] request.
  rpc Get(GetLoadBalancerRequest) returns (LoadBalancer) {
    option (google.api.http) = { get: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}" };
  }

  // Lists application load balancers in the specified folder.
  rpc List(ListLoadBalancersRequest) returns (ListLoadBalancersResponse) {
    option (google.api.http) = { get: "/apploadbalancer/v1/loadBalancers" };
  }

  // Creates an application load balancer in the specified folder.
  rpc Create(CreateLoadBalancerRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "CreateLoadBalancerMetadata"
      response: "LoadBalancer"
    };
  }

  // Updates the specified application load balancer.
  rpc Update(UpdateLoadBalancerRequest) returns (operation.Operation) {
    option (google.api.http) = { patch: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "UpdateLoadBalancerMetadata"
      response: "LoadBalancer"
    };
  }

  // Deletes the specified application load balancer.
  rpc Delete(DeleteLoadBalancerRequest) returns (operation.Operation) {
    option (google.api.http) = { delete: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}" };
    option (yandex.cloud.api.operation) = {
      metadata: "DeleteLoadBalancerMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Starts the specified application load balancer.
  rpc Start(StartLoadBalancerRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:start" };
    option (yandex.cloud.api.operation) = {
      metadata: "StartLoadBalancerMetadata"
      response: "LoadBalancer"
    };
  }

  // Stops the specified application load balancer.
  rpc Stop(StopLoadBalancerRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:stop" };
    option (yandex.cloud.api.operation) = {
      metadata: "StopLoadBalancerMetadata"
      response: "LoadBalancer"
    };
  }

  // AddListener/UpdateListener technically do the same, but have different semantics.

  // Adds a listener to the specified application load balancer.
  rpc AddListener(AddListenerRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:addListener" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "AddListenerMetadata"
      response: "LoadBalancer"
    };
  }

  // Deletes the specified listener.
  rpc RemoveListener(RemoveListenerRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:removeListener" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "RemoveListenerMetadata"
      response: "LoadBalancer"
    };
  }

  // Updates the specified listener of the specified application load balancer.
  rpc UpdateListener(UpdateListenerRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:updateListener" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "UpdateListenerMetadata"
      response: "LoadBalancer"
    };
  }

  // Adds a SNI handler to the specified listener.
  //
  // This request does not allow to add [TlsListener.default_handler]. Make an [UpdateListener] request instead.
  rpc AddSniMatch(AddSniMatchRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:addSniMatch" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "AddSniMatchMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Updates the specified SNI handler of the specified listener.
  //
  // This request does not allow to update [TlsListener.default_handler]. Make an [UpdateListener] request instead.
  rpc UpdateSniMatch(UpdateSniMatchRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:updateSniMatch" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "UpdateSniMatchMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Deletes the specified SNI handler.
  //
  // This request does not allow to delete [TlsListener.default_handler].
  rpc RemoveSniMatch(RemoveSniMatchRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}:removeSniMatch" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "RemoveSniMatchMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Returns the statuses of all targets of the specified backend group in all their availability zones.
  rpc GetTargetStates (GetTargetStatesRequest) returns (GetTargetStatesResponse) {
    option (google.api.http) = { get: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}/targetStates/{backend_group_id}/{target_group_id}" };
  }

  // Lists operations for the specified application load balancer.
  rpc ListOperations (ListLoadBalancerOperationsRequest) returns (ListLoadBalancerOperationsResponse) {
    option (google.api.http) = { get: "/apploadbalancer/v1/loadBalancers/{load_balancer_id}/operations" };
  }
}

message GetLoadBalancerRequest {
  // ID of the application load balancer to return.
  //
  // To get the application load balancer ID, make a [LoadBalancerService.List] request.
  string load_balancer_id = 1 [(required) = true];
}

message ListLoadBalancersRequest {
  // ID of the folder to list application load balancers in.
  //
  // To get the folder ID, make a [yandex.cloud.resourcemanager.v1.FolderService.List] request.
  string folder_id = 1 [(required) = true];

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

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

  // A filter expression that filters application load balancers listed in the response.
  //
  // The expression must specify:
  // 1. The field name. Currently you can use filtering only on [LoadBalancer.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 3-63 characters long and match the regular expression `^[a-z][-a-z0-9]{1,61}[a-z0-9]`.
  // Example of a filter: `name=my-load-balancer`.
  string filter = 4 [(length) = "<=1000"];
}

message ListLoadBalancersResponse {
  // List of application load balancers in the specified folder.
  repeated LoadBalancer load_balancers = 1;

  // Token for getting the next page of the list. If the number of results is greater than
  // the specified [ListLoadBalancersRequest.page_size], use `next_page_token` as the value
  // for the [ListLoadBalancersRequest.page_token] parameter in the next list request.
  //
  // Each subsequent page will have its own `next_page_token` to continue paging through the results.
  string next_page_token = 2;
}

message DeleteLoadBalancerRequest {
  // ID of the application load balancer to delete.
  //
  // To get the application load balancer ID, make a [LoadBalancerService.List] request.
  string load_balancer_id = 1 [(required) = true];
}

message DeleteLoadBalancerMetadata {
  // ID of the application load balancer that is being deleted.
  string load_balancer_id = 1;
}

message UpdateLoadBalancerRequest {
  // ID of the application load balancer to update.
  //
  // To get the application load balancer ID, make a [LoadBalancerService.List] request.
  string load_balancer_id = 1 [(required) = true];

  // Field mask that specifies which attributes of the application load balancer should be updated.
  google.protobuf.FieldMask update_mask = 2;

  // New name for the application load balancer.
  // The name must be unique within the folder.
  string name = 3 [(pattern) = "([a-z]([-a-z0-9]{0,61}[a-z0-9])?)?"];

  // New description of the application load balancer.
  string description = 4 [(length) = "<=256"];

  // New application load balancer labels as `key:value` pairs.
  // For details about the concept, see [documentation](/docs/overview/concepts/services#labels).
  //
  // Existing set of labels is completely replaced by the provided set, so if you just want
  // to add or remove a label:
  // 1. Get the current set of labels with a [LoadBalancerService.Get] request.
  // 2. Add or remove a label in this set.
  // 3. Send the new set in this field.
  map<string, string> labels = 5 [(size) = "<=64", (length) = "<=63", (pattern) = "[-_./\\@0-9a-z]*", (map_key).length = "1-63", (map_key).pattern = "[a-z][-_./\\@0-9a-z]*"];

  // New listeners for the application load balancer.
  //
  // For details about the concept,
  // see [documentation](/docs/application-load-balancer/concepts/application-load-balancer#listener).
  //
  // Existing list of listeners is completely replaced by the specified list, so if you just want to add, update,
  // or remove a listener, make a [LoadBalancerService.AddListener] request,
  // a [LoadBalancerService.UpdateListener] request, or a [LoadBalancerService.RemoveListener] request.
  repeated ListenerSpec listener_specs = 6;

  // New locality settings of the application load balancer.
  //
  // For details about the concept,
  // see [documentation](/docs/application-load-balancer/concepts/application-load-balancer#lb-location).
  //
  // Existing locality settings are completely replaced by the specified settings,
  // so if you just want to add or remove an allocation policy:
  // 1. Get the current settings with a [LoadBalancerService.Get] request.
  // 2. Add or remove a policy in this set.
  // 3. Send the new set in this field.
  AllocationPolicy allocation_policy = 7;

  // ID's of new security groups attributed to the application load balancer.
  //
  // For details about the concept,
  // see [documentation](/docs/application-load-balancer/concepts/application-load-balancer#security-groups).
  //
  // Existing list of security groups is completely replaced by the specified list,
  // so if you just want to add or remove an allocation policy:
  // 1. Get the current set of security groups with a [LoadBalancerService.Get] request.
  // 2. Add or remove a group in this set.
  // 3. Send the new set in this field.
  repeated string security_group_ids = 8;
}

message UpdateLoadBalancerMetadata {
  // ID of the application load balancer that is being updated.
  string load_balancer_id = 1;
}

message CreateLoadBalancerRequest {
  // ID of the folder to create an application load balancer in.
  //
  // To get the folder ID, make a [yandex.cloud.resourcemanager.v1.FolderService.List] request.
  string folder_id = 1 [(required) = true];

  // Name of the application load balancer.
  // The name must be unique within the folder.
  string name = 2 [(pattern) = "([a-z]([-a-z0-9]{0,61}[a-z0-9])?)?"];

  // Description of the application load balancer.
  string description = 3 [(length) = "<=256"];

  // Application load balancer labels as `key:value` pairs.
  // For details about the concept, see [documentation](/docs/overview/concepts/services#labels).
  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]*"];

  // ID of the region that the application load balancer is located at.
  //
  // The only supported value is `ru-central1`.
  string region_id = 5 [(required) = true];

  // ID of the network that the application load balancer belongs to.
  string network_id = 6 [(required) = true];

  // Listeners that belong to the application load balancer.
  //
  // For details about the concept,
  // see [documentation](/docs/application-load-balancer/concepts/application-load-balancer#listener).
  repeated ListenerSpec listener_specs = 7;

  // Locality settings of the application load balancer.
  //
  // For details about the concept,
  // see [documentation](/docs/application-load-balancer/concepts/application-load-balancer#lb-location).
  AllocationPolicy allocation_policy = 8;

  // ID's of the security groups attributed to the application load balancer.
  //
  // For details about the concept,
  // see [documentation](/docs/application-load-balancer/concepts/application-load-balancer#security-groups).
  repeated string security_group_ids = 9;
}

message CreateLoadBalancerMetadata {
  // ID of the application load balancer that is being created.
  string load_balancer_id = 1;
}

message StartLoadBalancerRequest {
  // ID of the application load balancer to start.
  //
  // The application load balancer must have a `STOPPED` status ([LoadBalancer.status]).
  //
  // To get the application load balancer ID, make a [LoadBalancerService.List] request.
  string load_balancer_id = 1 [(required) = true];
}

message StartLoadBalancerMetadata {
  // ID of the application load balancer that is being started.
  string load_balancer_id = 1;
}

message StopLoadBalancerRequest {
  // ID of the application load balancer to stop.
  //
  // The application load balancer must have an `ACTIVE` status ([LoadBalancer.status]).
  //
  // To get the application load balancer ID, make a [LoadBalancerService.List] request.
  string load_balancer_id = 1 [(required) = true];
}

message StopLoadBalancerMetadata {
  // ID of the application load balancer that is being stopped.
  string load_balancer_id = 1;
}

message AddListenerRequest {
  // ID of the application load balancer to add a listener to.
  string load_balancer_id = 1 [(required) = true];

  // Listener to add to the application load balancer.
  ListenerSpec listener_spec = 2 [(required) = true];
}

message AddListenerMetadata {
  // ID of the application load balancer that the listener is being added to.
  string load_balancer_id = 1;

  // Name of the listener that is being added to the application load balancer.
  string listener_name = 2;
}

message RemoveListenerRequest {
  // ID of the application load balancer to remove the listener from.
  string load_balancer_id = 1 [(required) = true];

  // Name of the listener to remove from the application load balancer.
  string name = 2 [(required) = true];
}

message RemoveListenerMetadata {
  // ID of the application load balancer that the listener is being removed from.
  string load_balancer_id = 1;

  // Name of the listener that is being removed from the application load balancer.
  string listener_name = 2;
}

message UpdateListenerRequest {
  // ID of the application load balancer to update the listener in.
  string load_balancer_id = 1 [(required) = true];

  // Field mask that specifies which attributes of the listener should be updated.
  google.protobuf.FieldMask update_mask = 2;

  // New attributes of the listener.
  ListenerSpec listener_spec = 3 [(required) = true];
}

message UpdateListenerMetadata {
  // ID of the application load balancer that the listener is being updated in.
  string load_balancer_id = 1;

  // Name of the listener that is being updated.
  string listener_name = 2;
}

message AddressSpec {
  // Endpoint address of one of the types: public (external) IPv4 address, internal IPv4 address, public IPv6 address.
  oneof address_spec {
    option (exactly_one) = true;

    // Public IPv4 endpoint address.
    ExternalIpv4AddressSpec external_ipv4_address_spec = 1;

    // Internal IPv4 endpoint address.
    //
    // To enable the use of listeners with internal addresses, [contact support](https://console.cloud.yandex.ru/support).
    InternalIpv4AddressSpec internal_ipv4_address_spec = 2;

    // Public IPv6 endpoint address.
    ExternalIpv6AddressSpec external_ipv6_address_spec = 3;
  }
}

message ExternalIpv4AddressSpec {
  // IPv4 address.
  string address = 1;
}

message InternalIpv4AddressSpec {
  // IPv4 address.
  string address = 1;

  // ID of the subnet that the address belongs to.
  string subnet_id = 2;
}

message ExternalIpv6AddressSpec {
  // IPv6 address.
  string address = 1;
}

message EndpointSpec {
  // Endpoint public (external) and internal addresses.
  repeated AddressSpec address_specs = 1 [(size) = ">0"];

  // Endpoint ports.
  repeated int64 ports = 2 [(size) = ">0", (value) = "1-65535"];
}

message ListenerSpec {
  // Name of the listener. The name is unique within the application load balancer.
  string name = 1 [(required) = true, (pattern) = "[a-z]([-a-z0-9]{0,61}[a-z0-9])?"];

  // Endpoints of the listener.
  //
  // Endpoints are defined by their IP addresses and ports.
  repeated EndpointSpec endpoint_specs = 2 [(size) = ">0"];

  // HTTP or HTTPS (HTTP over TLS) listener settings.
  oneof listener {
    option (exactly_one) = true;

    // HTTP listener settings.
    HttpListener http = 3;

    // HTTPS (HTTP over TLS) listener settings.
    TlsListener tls = 4;
  }
}

message GetTargetStatesRequest {
  // ID of the application load balancer that the backend group is attributed to.
  string load_balancer_id = 1 [(required) = true];

  // ID of the backend group that the target group is attributed to.
  string backend_group_id = 2 [(required) = true];

  // ID of the target group to get target states of.
  string target_group_id = 3 [(required) = true];
}

message GetTargetStatesResponse {
  // Target states of the specified target group.
  repeated TargetState target_states = 1;
}

message AddSniMatchRequest {
  // ID of the application load balancer to add a SNI handler to.
  string load_balancer_id = 1 [(required) = true];

  // Name of the listener to add a SNI handler to.
  string listener_name = 2 [(required) = true];

  // Name of the SNI handler to add.
  string name = 3 [(required) = true];

  // Server names that are matched by the SNI handler.
  repeated string server_names = 4 [(size) = ">0"];

  // Settings for handling requests with Server Name Indication (SNI) matching one of [server_names] values.
  TlsHandler handler = 5 [(required) = true];
}

message AddSniMatchMetadata {
  // ID of the application load balancer that the SNI handler is being added to.
  string load_balancer_id = 1;

  // Name of the listener that the SNI handler is being added to.
  string listener_name = 2;

  // Name of the SNI handler that is being added to the listener.
  string sni_match_name = 3;
}

message RemoveSniMatchRequest {
  // ID of the application load balancer to remove the SNI handler from.
  string load_balancer_id = 1 [(required) = true];

  // Name of the listener te remove the SNI handler from.
  string listener_name = 2 [(required) = true];

  // Name of the SNI handler to remove.
  string sni_match_name = 3 [(required) = true];
}

message RemoveSniMatchMetadata {
  // ID of the application load balancer that the SNI handler is being removed from.
  string load_balancer_id = 1;

  // Name of the listener that the SNI handler is being removed from.
  string listener_name = 2;

  // Name of the SNI handler that is being removed.
  string sni_match_name = 3;
}

message UpdateSniMatchRequest {
  // ID of the application load balancer to update the SNI handler in.
  string load_balancer_id = 1 [(required) = true];

  // Name of the listener to update the SNI handler in.
  string listener_name = 2 [(required) = true];

  // Name of the SNI handler to update.
  string name = 3 [(required) = true];

  // Field mask that specifies which attributes of the SNI handler should be updated.
  google.protobuf.FieldMask update_mask = 4;

  // New server names that are matched by the SNI handler.
  //
  // Existing set of server names is completely replaced by the provided set, so if you just want
  // to add or remove a server name:
  // 1. Get the current set of server names with a [LoadBalancerService.Get] request.
  // 2. Add or remove a server name in this set.
  // 3. Send the new set in this field.
  repeated string server_names = 5 [(size) = ">0"];

  // New settings for handling requests with Server Name Indication (SNI) matching one of [server_names] values.
  TlsHandler handler = 6 [(required) = true];
}

message UpdateSniMatchMetadata {
  // ID of the application load balancer that the SNI handler is being updated in.
  string load_balancer_id = 1;

  // Name of the listener that the SNI handler is being updated in.
  string listener_name = 2;

  // Name of the SNI handler that is being updated.
  string sni_match_name = 3;
}

message ListLoadBalancerOperationsRequest {
  // ID of the application load balancer to get operations for.
  //
  // To get the application load balancer ID, use a [LoadBalancerService.List] request.
  string load_balancer_id = 1 [(required) = true, (length) = "<=50"];

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

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

message ListLoadBalancerOperationsResponse {
  // List of operations for the specified application load balancer.
  repeated operation.Operation operations = 1;

  // Token for getting the next page of the list. If the number of results is greater than
  // the specified [ListLoadBalancerOperationsRequest.page_size], use `next_page_token` as the value
  // for the [ListLoadBalancerOperationsRequest.page_token] parameter in the next list request.
  //
  // Each subsequent page will have its own `next_page_token` to continue paging through the results.
  string next_page_token = 2;
}
