edition = "2023";

// If you make any changes make sure you run: make regenerate-proto

package gitlab.agent.managed_resources.rpc;

option go_package = "gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/module/managed_resources/rpc";
option features.field_presence = IMPLICIT;

import "buf/validate/validate.proto";
import "internal/module/managed_resources/managed_resources.proto";
import "pkg/entity/entity.proto";
import "pkg/constraint/constraint.proto";

message Object {
  string group = 1 [json_name = "group"]; // can be empty for the "core" group
  string version = 2 [json_name = "version", (buf.validate.field).string.min_bytes = 1];
  string kind = 3 [json_name = "kind", (buf.validate.field).string.min_bytes = 1];
  string namespace = 4 [json_name = "namespace"]; // can be empty e.g. for Namespace
  string name = 5 [json_name = "name", (buf.validate.field).string.min_bytes = 1];
}

message ObjectError {
  Object object = 1 [json_name = "object", (buf.validate.field).required = true];
  string error = 2 [json_name = "error", (buf.validate.field).string.min_bytes = 1];
}

message EnvironmentTemplateInfo {
  string agent_name = 1 [json_name = "agent_name", (buf.validate.field).string.(constraint.is_agent_name) = true];
  string template_name = 2 [json_name = "template_name", (buf.validate.field).string.min_bytes = 1];
}

message GetDefaultEnvironmentTemplateRequest {
}

message GetDefaultEnvironmentTemplateResponse {
  managed_resources.EnvironmentTemplate template = 1 [json_name = "template", (buf.validate.field).required = true];
}

message GetEnvironmentTemplateRequest {
  string template_name = 1 [(buf.validate.field).string.min_bytes = 1];
  string agent_name = 2 [(buf.validate.field).string.(constraint.is_agent_name) = true];

  // Fields below allow kas to fetch data from the agent configuration project.

  entity.GitalyInfo gitaly_info = 3 [(buf.validate.field).required = true];
  entity.GitalyRepository gitaly_repository = 4 [(buf.validate.field).required = true];
  string default_branch = 5 [(buf.validate.field).string.min_bytes = 1];
}

message GetEnvironmentTemplateResponse {
  managed_resources.EnvironmentTemplate template = 1 [json_name = "template", (buf.validate.field).required = true];
}

message RenderEnvironmentTemplateRequest {
  managed_resources.EnvironmentTemplate template = 1 [(buf.validate.field).required = true];
  managed_resources.TemplatingInfo info = 2 [(buf.validate.field).required = true];
}

message RenderEnvironmentTemplateResponse {
  managed_resources.RenderedEnvironmentTemplate template = 1 [json_name = "template", (buf.validate.field).required = true];
}

message ListEnvironmentTemplatesRequest {
  // if not specified, list for all agents.
  string agent_name = 1 [features.field_presence = EXPLICIT, (buf.validate.field).string.(constraint.is_agent_name) = true];

  // Fields below allow kas to fetch data from the agent configuration project.

  entity.GitalyInfo gitaly_info = 2 [(buf.validate.field).required = true];
  entity.GitalyRepository gitaly_repository = 3 [(buf.validate.field).required = true];
  string default_branch = 4 [(buf.validate.field).string.min_bytes = 1];
}

message ListEnvironmentTemplatesResponse {
  repeated EnvironmentTemplateInfo infos = 1 [json_name = "infos"];
}

message EnsureEnvironmentRequest {
  managed_resources.RenderedEnvironmentTemplate template = 1 [(buf.validate.field).required = true];
  managed_resources.TemplatingInfo info = 2 [(buf.validate.field).required = true];
}

message EnsureEnvironmentResponse {
  repeated Object objects = 1 [json_name = "objects"];
  repeated ObjectError errors = 2 [json_name = "errors"];
}

message DeleteEnvironmentRequest {
  int64 agent_id = 1 [(buf.validate.field).int64.gt = 0];
  int64 project_id = 2 [(buf.validate.field).int64.gt = 0];
  string environment_slug = 3 [(buf.validate.field).string.min_bytes = 1];
  repeated Object objects = 4;
}

message DeleteEnvironmentResponse {
  // List of found objects that were marked for deletion by this call or by previous calls but still exist.
  // Objects that:
  // - do not exist or
  // - have been updated to not belong to the environment that is being deleted
  // are not returned.
  repeated Object in_progress = 1 [json_name = "in_progress"];
  repeated ObjectError errors = 2 [json_name = "errors"];
}

service Provisioner {
  // Get the default environment template.
  rpc GetDefaultEnvironmentTemplate (GetDefaultEnvironmentTemplateRequest) returns (GetDefaultEnvironmentTemplateResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // List environment templates available in a repository for a particular or all agents.
  rpc ListEnvironmentTemplates (ListEnvironmentTemplatesRequest) returns (ListEnvironmentTemplatesResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // Get a particular environment template.
  rpc GetEnvironmentTemplate (GetEnvironmentTemplateRequest) returns (GetEnvironmentTemplateResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // Render an environment template.
  rpc RenderEnvironmentTemplate (RenderEnvironmentTemplateRequest) returns (RenderEnvironmentTemplateResponse) {
    option idempotency_level = NO_SIDE_EFFECTS;
  }
  // Ensure environment in the cluster matches the provided rendered template.
  rpc EnsureEnvironment (EnsureEnvironmentRequest) returns (EnsureEnvironmentResponse) {
    option idempotency_level = IDEMPOTENT;
  }
  // DeleteEnvironment has two purposes:
  // - to start the deletion process.
  // - to check the status of the deletion process. Objects in Kubernetes can have finalizers and may take an arbitrary
  //   amount of time to be actually deleted.
  //
  // Environment is considered fully deleted if this RPC returns an empty list of found objects and no errors.
  // To check the status, pass the list of objects the RPC returned back to it.
  // If there are errors, you may retry the operation by adding objects from the errors to the list of objects to delete.
  rpc DeleteEnvironment (DeleteEnvironmentRequest) returns (DeleteEnvironmentResponse) {
    option idempotency_level = IDEMPOTENT;
  }
}
