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/virtual_host.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 virtual hosts of HTTP routers.
service VirtualHostService {
  // Returns the specified virtual host.
  //
  // To get the list of all virtual hosts of an HTTP router, make a [List] request.
  rpc Get (GetVirtualHostRequest) returns (VirtualHost) {
    option (google.api.http) = { get: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts/{virtual_host_name}" };
  }

  // Lists virtual hosts of the specified HTTP router.
  rpc List (ListVirtualHostsRequest) returns (ListVirtualHostsResponse) {
    option (google.api.http) = { get: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts" };
  }

  // Creates a virtual host in the specified HTTP router.
  rpc Create (CreateVirtualHostRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "CreateVirtualHostMetadata"
      response: "VirtualHost"
    };
  }

  // Updates the specified virtual host of the specified HTTP router.
  rpc Update(UpdateVirtualHostRequest) returns (operation.Operation) {
    option (google.api.http) = { patch: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts/{virtual_host_name}" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "UpdateVirtualHostMetadata"
      response: "VirtualHost"
    };
  }

  // Deletes the specified virtual host.
  rpc Delete (DeleteVirtualHostRequest) returns (operation.Operation) {
    option (google.api.http) = { delete: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts/{virtual_host_name}" };
    option (yandex.cloud.api.operation) = {
      metadata: "DeleteVirtualHostMetadata"
      response: "google.protobuf.Empty"
    };
  }

  // Deletes the specified route from the specified virtual host.
  rpc RemoveRoute(RemoveRouteRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts/{virtual_host_name}:removeRoute" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "RemoveRouteMetadata"
      response: "VirtualHost"
    };
  }

  // Updates the specified route of the specified virtual host.
  rpc UpdateRoute(UpdateRouteRequest) returns (operation.Operation) {
    option (google.api.http) = { post: "/apploadbalancer/v1/httpRouters/{http_router_id}/virtualHosts/{virtual_host_name}:updateRoute" body: "*" };
    option (yandex.cloud.api.operation) = {
      metadata: "UpdateRouteMetadata"
      response: "VirtualHost"
    };
  }
}

message GetVirtualHostRequest {
  // ID of the HTTP router that the virtual host belongs to.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host to return.
  //
  // To get the virtual host name, make a [VirtualHostService.List] request.
  string virtual_host_name = 2 [(required) = true, (pattern) = "([a-z]([-a-z0-9]{0,61}[a-z0-9])?)?"];
}

message ListVirtualHostsRequest {
  // ID of the HTTP router to list virtual hosts in.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_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 [ListVirtualHostsResponse.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
  // [ListVirtualHostsResponse.next_page_token] returned by a previous list request.
  string page_token = 3 [(length) = "<=100"];
}

message ListVirtualHostsResponse {
  // List of virtual hosts of the specified HTTP router.
  repeated VirtualHost virtual_hosts = 1;

  // Token for getting the next page of the list. If the number of results is greater than
  // the specified [ListVirtualHostsRequest.page_size], use `next_page_token` as the value
  // for the [ListVirtualHostsRequest.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 CreateVirtualHostRequest {
  // ID of the HTTP router to create a virtual host in.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host. The name must be unique within the HTTP router and cannot be changed after creation.
  string name = 2 [(pattern) = "([a-z]([-a-z0-9]{0,61}[a-z0-9])?)?"];

  // List of domains that are attributed to the virtual host.
  //
  // The host is selected to process the request received by the load balancer
  // if the domain specified in the HTTP/1.1 `Host` header or the HTTP/2 `:authority` pseudo-header matches a domain
  // specified in the host.
  //
  // A wildcard asterisk character (`*`) matches 0 or more characters.
  //
  // If not specified, all domains are attributed to the host, which is the same as specifying a `*` value.
  // An HTTP router must not contain more than one virtual host to which all domains are attributed.
  repeated string authority = 3;

  // Routes of the virtual host.
  //
  // A route contains a set of conditions (predicates) that are used by the load balancer to select the route
  // for the request and an action on the request.
  // For details about the concept, see [documentation](/docs/application-load-balancer/concepts/http-router#routes).
  //
  // The order of routes matters: the first route whose predicate matches the request is selected.
  // The most specific routes should be at the top of the list, so that they are not overridden.
  // For example, if the first HTTP route is configured, via [HttpRoute.match], to match paths prefixed with just `/`,
  // other routes are never matched.
  repeated Route routes = 5;

  // Modifications that are made to the headers of incoming HTTP requests before they are forwarded to backends.
  repeated HeaderModification modify_request_headers = 6;

  // Modifications that are made to the headers of HTTP responses received from backends
  // before responses are forwarded to clients.
  repeated HeaderModification modify_response_headers = 7;
}

message CreateVirtualHostMetadata {
  // ID of the HTTP router that the virtual host is being created in.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host that is being created.
  string virtual_host_name = 2;
}

message UpdateVirtualHostRequest {
  // ID of the HTTP router to update a virtual host in.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host.
  //
  // Used only to refer to the virtual host. The name of a host cannot be changed.
  //
  // To get the virtual host name, make a [VirtualHostService.List] request.
  string virtual_host_name = 2 [(required) = true];

  // Field mask that specifies which attributes of the virtual host should be updated.
  google.protobuf.FieldMask update_mask = 3;

  // New list of domains to attribute to the virtual host.
  //
  // The host is selected to process the request received by the load balancer
  // if the domain specified in the HTTP/1.1 `Host` header or the HTTP/2 `:authority` pseudo-header matches a domain
  // specified in the host.
  //
  // A wildcard asterisk character (`*`) matches 0 or more characters.
  //
  // Existing list of domains is completely replaced by the specified list.
  //
  // If not specified, all domains are attributed to the host, which is the same as specifying a `*` value.
  // An HTTP router must not contain more than one virtual host to which all domains are attributed.
  repeated string authority = 4;

  // New list of routes of the virtual host.
  //
  // A route contains a set of conditions (predicates) that are used by the load balancer to select the route
  // for the request and an action on the request.
  // For details about the concept, see [documentation](/docs/application-load-balancer/concepts/http-router#routes).
  //
  // The order of routes matters: the first route whose predicate matches the request is selected.
  // The most specific routes should be at the top of the list, so that they are not overridden.
  // For example, if the first HTTP route is configured, via [HttpRoute.match], to match paths prefixed with just `/`,
  // other routes are never matched.
  //
  // Existing list of routes is completely replaced by the specified list, so if you just want to remove a route,
  // make a [VirtualHostService.RemoveRoute] request.
  repeated Route routes = 6;

  // New list of modifications that are made to the headers of incoming HTTP requests
  // before they are forwarded to backends.
  //
  // Existing list of modifications is completely replaced by the specified list.
  repeated HeaderModification modify_request_headers = 7;

  // New list of modifications that are made to the headers of HTTP responses received from backends
  // before responses are forwarded to clients.
  //
  // Existing list of modifications is completely replaced by the specified list.
  repeated HeaderModification modify_response_headers = 8;
}

message UpdateVirtualHostMetadata {
  // ID of the HTTP router that the virtual host is being updated in.
  string http_router_id = 1;

  // Name of the virtual host that is being updated.
  string virtual_host_name = 2;
}

message DeleteVirtualHostRequest {
  // ID of the HTTP router to delete a virtual host from.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host to delete.
  //
  // To get the virtual host name, make a [VirtualHostService.List] request.
  string virtual_host_name = 2 [(required) = true, (pattern) = "([a-z]([-a-z0-9]{0,61}[a-z0-9])?)?"];
}

message DeleteVirtualHostMetadata {
  // ID of the HTTP router that the virtual host is being deleted from.
  string http_router_id = 1;

  // Name of the virtual host that is being deleted.
  string virtual_host_name = 2;
}

message RemoveRouteRequest {
  // ID of the HTTP router to delete a route from.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host to delete a route from.
  //
  // To get the virtual host name, make a [VirtualHostService.List] request.
  string virtual_host_name = 2 [(required) = true];

  // Name of the route to delete.
  //
  // To get the route name, make a [VirtualHostService.Get] request.
  string route_name = 3 [(required) = true];
}

message RemoveRouteMetadata {
  // ID of the HTTP router that the route is being deleted from.
  string http_router_id = 1;

  // Name of the virtual host that the route is being deleted from.
  string virtual_host_name = 2;

  // Name of the route that is being deleted.
  string route_name = 3;
}

message UpdateRouteRequest {
  // ID of the HTTP router to update a route in.
  //
  // To get the HTTP router ID, make a [HttpRouterService.List] request.
  string http_router_id = 1 [(required) = true];

  // Name of the virtual host to update a route in.
  //
  // To get the virtual host name, make a [VirtualHostService.List] request.
  string virtual_host_name = 2 [(required) = true];

  // Name of the route to update.
  //
  // To get the route name, make a [VirtualHostService.Get] request.
  string route_name = 3 [(required) = true];

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

  // New settings of the route.
  oneof route {
    option (exactly_one) = true;

    // New settings of the HTTP route.
    HttpRoute http = 5;

    // New settings of the gRPC route.
    GrpcRoute grpc = 6;
  }
}

message UpdateRouteMetadata {
  // ID of the HTTP router that the route is being updated in.
  string http_router_id = 1;

  // Name of the virtual host that the route is being updated in.
  string virtual_host_name = 2;

  // Name of the route that is being updated.
  string route_name = 3;
}
