// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.appengine.v1beta;

import "google/appengine/v1beta/app_yaml.proto";
import "google/appengine/v1beta/deploy.proto";
import "google/appengine/v1beta/network_settings.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";

option csharp_namespace = "Google.Cloud.AppEngine.V1Beta";
option go_package = "google.golang.org/genproto/googleapis/appengine/v1beta;appengine";
option java_multiple_files = true;
option java_outer_classname = "VersionProto";
option java_package = "com.google.appengine.v1beta";
option php_namespace = "Google\\Cloud\\AppEngine\\V1beta";
option ruby_package = "Google::Cloud::AppEngine::V1beta";

// A Version resource is a specific set of source code and configuration files
// that are deployed into a service.
message Version {
  // Full path to the Version resource in the API.  Example:
  // `apps/myapp/services/default/versions/v1`.
  //
  // @OutputOnly
  string name = 1;

  // Relative name of the version within the service.  Example: `v1`.
  // Version names can contain only lowercase letters, numbers, or hyphens.
  // Reserved names: "default", "latest", and any name with the prefix "ah-".
  string id = 2;

  // Controls how instances are created, scaled, and reaped.
  //
  // Defaults to `AutomaticScaling`.
  oneof scaling {
    // Automatic scaling is based on request rate, response latencies, and other
    // application metrics. Instances are dynamically created and destroyed as
    // needed in order to handle traffic.
    AutomaticScaling automatic_scaling = 3;

    // A service with basic scaling will create an instance when the application
    // receives a request. The instance will be turned down when the app becomes
    // idle. Basic scaling is ideal for work that is intermittent or driven by
    // user activity.
    BasicScaling basic_scaling = 4;

    // A service with manual scaling runs continuously, allowing you to perform
    // complex initialization and rely on the state of its memory over time.
    // Manually scaled versions are sometimes referred to as "backends".
    ManualScaling manual_scaling = 5;
  }

  // Before an application can receive email or XMPP messages, the application
  // must be configured to enable the service.
  repeated InboundServiceType inbound_services = 6;

  // Instance class that is used to run this version. Valid values are:
  //
  // * AutomaticScaling: `F1`, `F2`, `F4`, `F4_1G`
  // * ManualScaling or BasicScaling: `B1`, `B2`, `B4`, `B8`, `B4_1G`
  //
  // Defaults to `F1` for AutomaticScaling and `B1` for ManualScaling or
  // BasicScaling.
  string instance_class = 7;

  // Extra network settings.
  // Only applicable in the App Engine flexible environment.
  Network network = 8;

  // The Google Compute Engine zones that are supported by this version in the
  // App Engine flexible environment. Deprecated.
  repeated string zones = 118;

  // Machine resources for this version.
  // Only applicable in the App Engine flexible environment.
  Resources resources = 9;

  // Desired runtime. Example: `python27`.
  string runtime = 10;

  // The channel of the runtime to use. Only available for some
  // runtimes. Defaults to the `default` channel.
  string runtime_channel = 117;

  // Whether multiple requests can be dispatched to this version at once.
  bool threadsafe = 11;

  // Whether to deploy this version in a container on a virtual machine.
  bool vm = 12;

  // app_engine_apis allows second generation runtimes to access the
  // App Engine APIs.
  bool app_engine_apis = 128;

  // Metadata settings that are supplied to this version to enable
  // beta runtime features.
  map<string, string> beta_settings = 13;

  // App Engine execution environment for this version.
  //
  // Defaults to `standard`.
  string env = 14;

  // Current serving status of this version. Only the versions with a
  // `SERVING` status create instances and can be billed.
  //
  // `SERVING_STATUS_UNSPECIFIED` is an invalid value. Defaults to `SERVING`.
  ServingStatus serving_status = 15;

  // Email address of the user who created this version.
  //
  // @OutputOnly
  string created_by = 16;

  // Time that this version was created.
  //
  // @OutputOnly
  google.protobuf.Timestamp create_time = 17;

  // Total size in bytes of all the files that are included in this version
  // and currently hosted on the App Engine disk.
  //
  // @OutputOnly
  int64 disk_usage_bytes = 18;

  // The version of the API in the given runtime environment. Please see the
  // app.yaml reference for valid values at
  // https://cloud.google.com/appengine/docs/standard/<language>/config/appref
  string runtime_api_version = 21;

  // The path or name of the app's main executable.
  string runtime_main_executable_path = 22;

  // The identity that the deployed version will run as.
  // Admin API will use the App Engine Appspot service account as default if
  // this field is neither provided in app.yaml file nor through CLI flag.
  string service_account = 127;

  // An ordered list of URL-matching patterns that should be applied to incoming
  // requests. The first matching URL handles the request and other request
  // handlers are not attempted.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  repeated UrlMap handlers = 100;

  // Custom static error pages. Limited to 10KB per page.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  repeated ErrorHandler error_handlers = 101;

  // Configuration for third-party Python runtime libraries that are required
  // by the application.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  repeated Library libraries = 102;

  // Serving configuration for
  // [Google Cloud Endpoints](https://cloud.google.com/appengine/docs/python/endpoints/).
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  ApiConfigHandler api_config = 103;

  // Environment variables available to the application.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  map<string, string> env_variables = 104;

  // Environment variables available to the build environment.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  map<string, string> build_env_variables = 125;

  // Duration that static files should be cached by web proxies and browsers.
  // Only applicable if the corresponding
  // [StaticFilesHandler](https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1beta/apps.services.versions#StaticFilesHandler)
  // does not specify its own expiration time.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  google.protobuf.Duration default_expiration = 105;

  // Configures health checking for instances. Unhealthy instances are
  // stopped and replaced with new instances.
  // Only applicable in the App Engine flexible environment.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  HealthCheck health_check = 106;

  // Configures readiness health checking for instances.
  // Unhealthy instances are not put into the backend traffic rotation.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  ReadinessCheck readiness_check = 112;

  // Configures liveness health checking for instances.
  // Unhealthy instances are stopped and replaced with new instances
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  LivenessCheck liveness_check = 113;

  // Files that match this pattern will not be built into this version.
  // Only applicable for Go runtimes.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  string nobuild_files_regex = 107;

  // Code and application artifacts that make up this version.
  //
  // Only returned in `GET` requests if `view=FULL` is set.
  Deployment deployment = 108;

  // Serving URL for this version. Example:
  // "https://myversion-dot-myservice-dot-myapp.appspot.com"
  //
  // @OutputOnly
  string version_url = 109;

  // Cloud Endpoints configuration.
  //
  // If endpoints_api_service is set, the Cloud Endpoints Extensible Service
  // Proxy will be provided to serve the API implemented by the app.
  EndpointsApiService endpoints_api_service = 110;

  // The entrypoint for the application.
  Entrypoint entrypoint = 122;

  // Enables VPC connectivity for standard apps.
  VpcAccessConnector vpc_access_connector = 121;
}

// [Cloud Endpoints](https://cloud.google.com/endpoints) configuration.
// The Endpoints API Service provides tooling for serving Open API and gRPC
// endpoints via an NGINX proxy. Only valid for App Engine Flexible environment
// deployments.
//
// The fields here refer to the name and configuration ID of a "service"
// resource in the [Service Management API](https://cloud.google.com/service-management/overview).
message EndpointsApiService {
  // Available rollout strategies.
  enum RolloutStrategy {
    // Not specified. Defaults to `FIXED`.
    UNSPECIFIED_ROLLOUT_STRATEGY = 0;

    // Endpoints service configuration ID will be fixed to the configuration ID
    // specified by `config_id`.
    FIXED = 1;

    // Endpoints service configuration ID will be updated with each rollout.
    MANAGED = 2;
  }

  // Endpoints service name which is the name of the "service" resource in the
  // Service Management API. For example "myapi.endpoints.myproject.cloud.goog"
  string name = 1;

  // Endpoints service configuration ID as specified by the Service Management
  // API. For example "2016-09-19r1".
  //
  // By default, the rollout strategy for Endpoints is `RolloutStrategy.FIXED`.
  // This means that Endpoints starts up with a particular configuration ID.
  // When a new configuration is rolled out, Endpoints must be given the new
  // configuration ID. The `config_id` field is used to give the configuration
  // ID and is required in this case.
  //
  // Endpoints also has a rollout strategy called `RolloutStrategy.MANAGED`.
  // When using this, Endpoints fetches the latest configuration and does not
  // need the configuration ID. In this case, `config_id` must be omitted.
  string config_id = 2;

  // Endpoints rollout strategy. If `FIXED`, `config_id` must be specified. If
  // `MANAGED`, `config_id` must be omitted.
  RolloutStrategy rollout_strategy = 3;

  // Enable or disable trace sampling. By default, this is set to false for
  // enabled.
  bool disable_trace_sampling = 4;
}

// Automatic scaling is based on request rate, response latencies, and other
// application metrics.
message AutomaticScaling {
  // The time period that the
  // [Autoscaler](https://cloud.google.com/compute/docs/autoscaler/)
  // should wait before it starts collecting information from a new instance.
  // This prevents the autoscaler from collecting information when the instance
  // is initializing, during which the collected usage would not be reliable.
  // Only applicable in the App Engine flexible environment.
  google.protobuf.Duration cool_down_period = 1;

  // Target scaling by CPU usage.
  CpuUtilization cpu_utilization = 2;

  // Number of concurrent requests an automatic scaling instance can accept
  // before the scheduler spawns a new instance.
  //
  // Defaults to a runtime-specific value.
  int32 max_concurrent_requests = 3;

  // Maximum number of idle instances that should be maintained for this
  // version.
  int32 max_idle_instances = 4;

  // Maximum number of instances that should be started to handle requests for
  // this version.
  int32 max_total_instances = 5;

  // Maximum amount of time that a request should wait in the pending queue
  // before starting a new instance to handle it.
  google.protobuf.Duration max_pending_latency = 6;

  // Minimum number of idle instances that should be maintained for
  // this version. Only applicable for the default version of a service.
  int32 min_idle_instances = 7;

  // Minimum number of running instances that should be maintained for this
  // version.
  int32 min_total_instances = 8;

  // Minimum amount of time a request should wait in the pending queue before
  // starting a new instance to handle it.
  google.protobuf.Duration min_pending_latency = 9;

  // Target scaling by request utilization.
  RequestUtilization request_utilization = 10;

  // Target scaling by disk usage.
  DiskUtilization disk_utilization = 11;

  // Target scaling by network usage.
  NetworkUtilization network_utilization = 12;

  // Target scaling by user-provided metrics.
  // Only applicable in the App Engine flexible environment.
  repeated CustomMetric custom_metrics = 21;

  // Scheduler settings for standard environment.
  StandardSchedulerSettings standard_scheduler_settings = 20;
}

// A service with basic scaling will create an instance when the application
// receives a request. The instance will be turned down when the app becomes
// idle. Basic scaling is ideal for work that is intermittent or driven by
// user activity.
message BasicScaling {
  // Duration of time after the last request that an instance must wait before
  // the instance is shut down.
  google.protobuf.Duration idle_timeout = 1;

  // Maximum number of instances to create for this version.
  int32 max_instances = 2;
}

// A service with manual scaling runs continuously, allowing you to perform
// complex initialization and rely on the state of its memory over time.
message ManualScaling {
  // Number of instances to assign to the service at the start. This number
  // can later be altered by using the
  // [Modules API](https://cloud.google.com/appengine/docs/python/modules/functions)
  // `set_num_instances()` function.
  int32 instances = 1;
}

// Target scaling by CPU usage.
message CpuUtilization {
  // Period of time over which CPU utilization is calculated.
  google.protobuf.Duration aggregation_window_length = 1;

  // Target CPU utilization ratio to maintain when scaling. Must be between 0
  // and 1.
  double target_utilization = 2;
}

// Target scaling by request utilization.
// Only applicable in the App Engine flexible environment.
message RequestUtilization {
  // Target requests per second.
  int32 target_request_count_per_second = 1;

  // Target number of concurrent requests.
  int32 target_concurrent_requests = 2;
}

// Target scaling by disk usage.
// Only applicable in the App Engine flexible environment.
message DiskUtilization {
  // Target bytes written per second.
  int32 target_write_bytes_per_second = 14;

  // Target ops written per second.
  int32 target_write_ops_per_second = 15;

  // Target bytes read per second.
  int32 target_read_bytes_per_second = 16;

  // Target ops read per seconds.
  int32 target_read_ops_per_second = 17;
}

// Target scaling by network usage.
// Only applicable in the App Engine flexible environment.
message NetworkUtilization {
  // Target bytes sent per second.
  int32 target_sent_bytes_per_second = 1;

  // Target packets sent per second.
  int32 target_sent_packets_per_second = 11;

  // Target bytes received per second.
  int32 target_received_bytes_per_second = 12;

  // Target packets received per second.
  int32 target_received_packets_per_second = 13;
}

// Allows autoscaling based on Stackdriver metrics.
message CustomMetric {
  // The name of the metric.
  string metric_name = 1;

  // The type of the metric. Must be a string representing a Stackdriver
  // metric type e.g. GAGUE, DELTA_PER_SECOND, etc.
  string target_type = 2;

  // The target spec.
  oneof target_spec {
    // The target value for the metric.
    double target_utilization = 3;

    // May be used instead of `target_utilization` when an instance can handle a
    // specific amount of work/resources and the metric value is equal to the
    // current amount of work remaining. The autoscaler will try to keep the
    // number of instances equal to the metric value divided by
    // `single_instance_assignment`.
    double single_instance_assignment = 4;
  }

  // Allows filtering on the metric's fields.
  string filter = 5;
}

// Scheduler settings for standard environment.
message StandardSchedulerSettings {
  // Target CPU utilization ratio to maintain when scaling.
  double target_cpu_utilization = 1;

  // Target throughput utilization ratio to maintain when scaling
  double target_throughput_utilization = 2;

  // Minimum number of instances to run for this version. Set to zero to disable
  // `min_instances` configuration.
  int32 min_instances = 3;

  // Maximum number of instances to run for this version. Set to zero to disable
  // `max_instances` configuration.
  int32 max_instances = 4;
}

// Extra network settings.
// Only applicable in the App Engine flexible environment.
message Network {
  // List of ports, or port pairs, to forward from the virtual machine to the
  // application container.
  // Only applicable in the App Engine flexible environment.
  repeated string forwarded_ports = 1;

  // Tag to apply to the instance during creation.
  // Only applicable in the App Engine flexible environment.
  string instance_tag = 2;

  // Google Compute Engine network where the virtual machines are created.
  // Specify the short name, not the resource path.
  //
  // Defaults to `default`.
  string name = 3;

  // Google Cloud Platform sub-network where the virtual machines are created.
  // Specify the short name, not the resource path.
  //
  // If a subnetwork name is specified, a network name will also be required
  // unless it is for the default network.
  //
  // * If the network that the instance is being created in is a Legacy network,
  // then the IP address is allocated from the IPv4Range.
  // * If the network that the instance is being created in is an auto Subnet
  // Mode Network, then only network name should be specified (not the
  // subnetwork_name) and the IP address is created from the IPCidrRange of the
  // subnetwork that exists in that zone for that network.
  // * If the network that the instance is being created in is a custom Subnet
  // Mode Network, then the subnetwork_name must be specified and the
  // IP address is created from the IPCidrRange of the subnetwork.
  //
  // If specified, the subnetwork must exist in the same region as the
  // App Engine flexible environment application.
  string subnetwork_name = 4;

  // Enable session affinity.
  // Only applicable in the App Engine flexible environment.
  bool session_affinity = 5;
}

// Volumes mounted within the app container.
// Only applicable in the App Engine flexible environment.
message Volume {
  // Unique name for the volume.
  string name = 1;

  // Underlying volume type, e.g. 'tmpfs'.
  string volume_type = 2;

  // Volume size in gigabytes.
  double size_gb = 3;
}

// Machine resources for a version.
message Resources {
  // Number of CPU cores needed.
  double cpu = 1;

  // Disk size (GB) needed.
  double disk_gb = 2;

  // Memory (GB) needed.
  double memory_gb = 3;

  // User specified volumes.
  repeated Volume volumes = 4;

  // The name of the encryption key that is stored in Google Cloud KMS.
  // Only should be used by Cloud Composer to encrypt the vm disk
  string kms_key_reference = 5;
}

// VPC access connector specification.
message VpcAccessConnector {
  // Full Serverless VPC Access Connector name e.g.
  // /projects/my-project/locations/us-central1/connectors/c1.
  string name = 1;
}

// The entrypoint for the application.
message Entrypoint {
  // The command to run.
  oneof command {
    // The format should be a shell command that can be fed to `bash -c`.
    string shell = 1;
  }
}

// Available inbound services.
enum InboundServiceType {
  // Not specified.
  INBOUND_SERVICE_UNSPECIFIED = 0;

  // Allows an application to receive mail.
  INBOUND_SERVICE_MAIL = 1;

  // Allows an application to receive email-bound notifications.
  INBOUND_SERVICE_MAIL_BOUNCE = 2;

  // Allows an application to receive error stanzas.
  INBOUND_SERVICE_XMPP_ERROR = 3;

  // Allows an application to receive instant messages.
  INBOUND_SERVICE_XMPP_MESSAGE = 4;

  // Allows an application to receive user subscription POSTs.
  INBOUND_SERVICE_XMPP_SUBSCRIBE = 5;

  // Allows an application to receive a user's chat presence.
  INBOUND_SERVICE_XMPP_PRESENCE = 6;

  // Registers an application for notifications when a client connects or
  // disconnects from a channel.
  INBOUND_SERVICE_CHANNEL_PRESENCE = 7;

  // Enables warmup requests.
  INBOUND_SERVICE_WARMUP = 9;
}

// Run states of a version.
enum ServingStatus {
  // Not specified.
  SERVING_STATUS_UNSPECIFIED = 0;

  // Currently serving. Instances are created according to the
  // scaling settings of the version.
  SERVING = 1;

  // Disabled. No instances will be created and the scaling
  // settings are ignored until the state of the version changes
  // to `SERVING`.
  STOPPED = 2;
}
