// Copyright 2022 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.cloud.gkemulticloud.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/gkemulticloud/v1/common_resources.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.GkeMultiCloud.V1";
option go_package = "cloud.google.com/go/gkemulticloud/apiv1/gkemulticloudpb;gkemulticloudpb";
option java_multiple_files = true;
option java_outer_classname = "AwsResourcesProto";
option java_package = "com.google.cloud.gkemulticloud.v1";
option php_namespace = "Google\\Cloud\\GkeMultiCloud\\V1";
option ruby_package = "Google::Cloud::GkeMultiCloud::V1";

// An Anthos cluster running on AWS.
message AwsCluster {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AwsCluster"
    pattern: "projects/{project}/locations/{location}/awsClusters/{aws_cluster}"
  };

  // The lifecycle state of the cluster.
  enum State {
    // Not set.
    STATE_UNSPECIFIED = 0;

    // The PROVISIONING state indicates the cluster is being created.
    PROVISIONING = 1;

    // The RUNNING state indicates the cluster has been created and is fully
    // usable.
    RUNNING = 2;

    // The RECONCILING state indicates that some work is actively being done on
    // the cluster, such as upgrading the control plane replicas.
    RECONCILING = 3;

    // The STOPPING state indicates the cluster is being deleted.
    STOPPING = 4;

    // The ERROR state indicates the cluster is in a broken unrecoverable
    // state.
    ERROR = 5;

    // The DEGRADED state indicates the cluster requires user action to
    // restore full functionality.
    DEGRADED = 6;
  }

  // The name of this resource.
  //
  // Cluster names are formatted as
  // `projects/<project-number>/locations/<region>/awsClusters/<cluster-id>`.
  //
  // See [Resource Names](https://cloud.google.com/apis/design/resource_names)
  // for more details on Google Cloud Platform resource names.
  string name = 1;

  // Optional. A human readable description of this cluster.
  // Cannot be longer than 255 UTF-8 encoded bytes.
  string description = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. Cluster-wide networking configuration.
  AwsClusterNetworking networking = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The AWS region where the cluster runs.
  //
  // Each Google Cloud region supports a subset of nearby AWS regions.
  // You can call
  // [GetAwsServerConfig][google.cloud.gkemulticloud.v1.AwsClusters.GetAwsServerConfig]
  // to list all supported AWS regions within a given Google Cloud region.
  string aws_region = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. Configuration related to the cluster control plane.
  AwsControlPlane control_plane = 5 [(google.api.field_behavior) = REQUIRED];

  // Required. Configuration related to the cluster RBAC settings.
  AwsAuthorization authorization = 15 [(google.api.field_behavior) = REQUIRED];

  // Output only. The current state of the cluster.
  State state = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The endpoint of the cluster's API server.
  string endpoint = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A globally unique identifier for the cluster.
  string uid = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. If set, there are currently changes in flight to the cluster.
  bool reconciling = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which this cluster was created.
  google.protobuf.Timestamp create_time = 11
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which this cluster was last updated.
  google.protobuf.Timestamp update_time = 12
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Allows clients to perform consistent read-modify-writes
  // through optimistic concurrency control.
  //
  // Can be sent on update and delete requests to ensure the
  // client has an up-to-date value before proceeding.
  string etag = 13;

  // Optional. Annotations on the cluster.
  //
  // This field has the same restrictions as Kubernetes annotations.
  // The total size of all keys and values combined is limited to 256k.
  // Key can have 2 segments: prefix (optional) and name (required),
  // separated by a slash (/).
  // Prefix must be a DNS subdomain.
  // Name must be 63 characters or less, begin and end with alphanumerics,
  // with dashes (-), underscores (_), dots (.), and alphanumerics between.
  map<string, string> annotations = 14 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Workload Identity settings.
  WorkloadIdentityConfig workload_identity_config = 16
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. PEM encoded x509 certificate of the cluster root of trust.
  string cluster_ca_certificate = 17
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. Fleet configuration.
  Fleet fleet = 18 [(google.api.field_behavior) = REQUIRED];

  // Optional. Logging configuration for this cluster.
  LoggingConfig logging_config = 19 [(google.api.field_behavior) = OPTIONAL];

  // Output only. A set of errors found in the cluster.
  repeated AwsClusterError errors = 20
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Monitoring configuration for this cluster.
  MonitoringConfig monitoring_config = 21
      [(google.api.field_behavior) = OPTIONAL];
}

// ControlPlane defines common parameters between control plane nodes.
message AwsControlPlane {
  // Required. The Kubernetes version to run on control plane replicas
  // (e.g. `1.19.10-gke.1000`).
  //
  // You can list all supported versions on a given Google Cloud region by
  // calling
  // [GetAwsServerConfig][google.cloud.gkemulticloud.v1.AwsClusters.GetAwsServerConfig].
  string version = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The AWS instance type.
  //
  // When unspecified, it uses a default based on the cluster's version.
  string instance_type = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. SSH configuration for how to access the underlying control plane
  // machines.
  AwsSshConfig ssh_config = 14 [(google.api.field_behavior) = OPTIONAL];

  // Required. The list of subnets where control plane replicas will run.
  // A replica will be provisioned on each subnet and up to three values
  // can be provided.
  // Each subnet must be in a different AWS Availability Zone (AZ).
  repeated string subnet_ids = 4 [(google.api.field_behavior) = REQUIRED];

  // Optional. The IDs of additional security groups to add to control plane
  // replicas. The Anthos Multi-Cloud API will automatically create and manage
  // security groups with the minimum rules needed for a functioning cluster.
  repeated string security_group_ids = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The name or ARN of the AWS IAM instance profile to assign to each
  // control plane replica.
  string iam_instance_profile = 7 [(google.api.field_behavior) = REQUIRED];

  // Optional. Configuration related to the root volume provisioned for each
  // control plane replica.
  //
  // Volumes will be provisioned in the availability zone associated
  // with the corresponding subnet.
  //
  // When unspecified, it defaults to 32 GiB with the GP2 volume type.
  AwsVolumeTemplate root_volume = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Configuration related to the main volume provisioned for each
  // control plane replica.
  // The main volume is in charge of storing all of the cluster's etcd state.
  //
  // Volumes will be provisioned in the availability zone associated
  // with the corresponding subnet.
  //
  // When unspecified, it defaults to 8 GiB with the GP2 volume type.
  AwsVolumeTemplate main_volume = 9 [(google.api.field_behavior) = OPTIONAL];

  // Required. The ARN of the AWS KMS key used to encrypt cluster secrets.
  AwsDatabaseEncryption database_encryption = 10
      [(google.api.field_behavior) = REQUIRED];

  // Optional. A set of AWS resource tags to propagate to all underlying managed
  // AWS resources.
  //
  // Specify at most 50 pairs containing alphanumerics, spaces, and symbols
  // (.+-=_:@/). Keys can be up to 127 Unicode characters. Values can be up to
  // 255 Unicode characters.
  map<string, string> tags = 11 [(google.api.field_behavior) = OPTIONAL];

  // Required. Authentication configuration for management of AWS resources.
  AwsServicesAuthentication aws_services_authentication = 12
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Proxy configuration for outbound HTTP(S) traffic.
  AwsProxyConfig proxy_config = 16 [(google.api.field_behavior) = OPTIONAL];

  // Required. Config encryption for user data.
  AwsConfigEncryption config_encryption = 17
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The placement to use on control plane instances.
  // When unspecified, the VPC's default tenancy will be used.
  AwsInstancePlacement instance_placement = 18
      [(google.api.field_behavior) = OPTIONAL];
}

// Authentication configuration for the management of AWS resources.
message AwsServicesAuthentication {
  // Required. The Amazon Resource Name (ARN) of the role that the Anthos
  // Multi-Cloud API will assume when managing AWS resources on your account.
  string role_arn = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. An identifier for the assumed role session.
  //
  // When unspecified, it defaults to `multicloud-service-agent`.
  string role_session_name = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Configuration related to the cluster RBAC settings.
message AwsAuthorization {
  // Required. Users that can perform operations as a cluster admin. A managed
  // ClusterRoleBinding will be created to grant the `cluster-admin` ClusterRole
  // to the users. Up to ten admin users can be provided.
  //
  // For more info on RBAC, see
  // https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
  repeated AwsClusterUser admin_users = 1
      [(google.api.field_behavior) = REQUIRED];
}

// Identities of a user-type subject for AWS clusters.
message AwsClusterUser {
  // Required. The name of the user, e.g. `my-gcp-id@gmail.com`.
  string username = 1 [(google.api.field_behavior) = REQUIRED];
}

// Configuration related to application-layer secrets encryption.
message AwsDatabaseEncryption {
  // Required. The ARN of the AWS KMS key used to encrypt cluster secrets.
  string kms_key_arn = 1 [(google.api.field_behavior) = REQUIRED];
}

// Configuration template for AWS EBS volumes.
message AwsVolumeTemplate {
  // Types of supported EBS volumes. We currently only support GP2 or GP3
  // volumes.
  // See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
  // for more information.
  enum VolumeType {
    // Not set.
    VOLUME_TYPE_UNSPECIFIED = 0;

    // GP2 (General Purpose SSD volume type).
    GP2 = 1;

    // GP3 (General Purpose SSD volume type).
    GP3 = 2;
  }

  // Optional. The size of the volume, in GiBs.
  //
  // When unspecified, a default value is provided. See the specific reference
  // in the parent resource.
  int32 size_gib = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Type of the EBS volume.
  //
  // When unspecified, it defaults to GP2 volume.
  VolumeType volume_type = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The number of I/O operations per second (IOPS) to provision for
  // GP3 volume.
  int32 iops = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The Amazon Resource Name (ARN) of the Customer Managed Key (CMK)
  // used to encrypt AWS EBS volumes.
  //
  // If not specified, the default Amazon managed key associated to
  // the AWS region where this cluster runs will be used.
  string kms_key_arn = 4 [(google.api.field_behavior) = OPTIONAL];
}

// ClusterNetworking defines cluster-wide networking configuration.
//
// Anthos clusters on AWS run on a single VPC. This includes control
// plane replicas and node pool nodes.
message AwsClusterNetworking {
  // Required. The VPC associated with the cluster. All component clusters
  // (i.e. control plane and node pools) run on a single VPC.
  //
  // This field cannot be changed after creation.
  string vpc_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. All pods in the cluster are assigned an IPv4 address from these
  // ranges. Only a single range is supported. This field cannot be changed
  // after creation.
  repeated string pod_address_cidr_blocks = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. All services in the cluster are assigned an IPv4 address from
  // these ranges. Only a single range is supported. This field cannot be
  // changed after creation.
  repeated string service_address_cidr_blocks = 3
      [(google.api.field_behavior) = REQUIRED];
}

// An Anthos node pool running on AWS.
message AwsNodePool {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AwsNodePool"
    pattern: "projects/{project}/locations/{location}/awsClusters/{aws_cluster}/awsNodePools/{aws_node_pool}"
  };

  // The lifecycle state of the node pool.
  enum State {
    // Not set.
    STATE_UNSPECIFIED = 0;

    // The PROVISIONING state indicates the node pool is being created.
    PROVISIONING = 1;

    // The RUNNING state indicates the node pool has been created
    // and is fully usable.
    RUNNING = 2;

    // The RECONCILING state indicates that the node pool is being reconciled.
    RECONCILING = 3;

    // The STOPPING state indicates the node pool is being deleted.
    STOPPING = 4;

    // The ERROR state indicates the node pool is in a broken unrecoverable
    // state.
    ERROR = 5;

    // The DEGRADED state indicates the node pool requires user action to
    // restore full functionality.
    DEGRADED = 6;
  }

  // The name of this resource.
  //
  // Node pool names are formatted as
  // `projects/<project-number>/locations/<region>/awsClusters/<cluster-id>/awsNodePools/<node-pool-id>`.
  //
  // For more details on Google Cloud resource names,
  // see [Resource Names](https://cloud.google.com/apis/design/resource_names)
  string name = 1;

  // Required. The Kubernetes version to run on this node pool (e.g.
  // `1.19.10-gke.1000`).
  //
  // You can list all supported versions on a given Google Cloud region by
  // calling
  // [GetAwsServerConfig][google.cloud.gkemulticloud.v1.AwsClusters.GetAwsServerConfig].
  string version = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The configuration of the node pool.
  AwsNodeConfig config = 28 [(google.api.field_behavior) = REQUIRED];

  // Required. Autoscaler configuration for this node pool.
  AwsNodePoolAutoscaling autoscaling = 25
      [(google.api.field_behavior) = REQUIRED];

  // Required. The subnet where the node pool node run.
  string subnet_id = 6 [(google.api.field_behavior) = REQUIRED];

  // Output only. The lifecycle state of the node pool.
  State state = 16 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A globally unique identifier for the node pool.
  string uid = 17 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. If set, there are currently changes in flight to the node
  // pool.
  bool reconciling = 18 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which this node pool was created.
  google.protobuf.Timestamp create_time = 19
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which this node pool was last updated.
  google.protobuf.Timestamp update_time = 20
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Allows clients to perform consistent read-modify-writes
  // through optimistic concurrency control.
  //
  // Can be sent on update and delete requests to ensure the
  // client has an up-to-date value before proceeding.
  string etag = 21;

  // Optional. Annotations on the node pool.
  //
  // This field has the same restrictions as Kubernetes annotations.
  // The total size of all keys and values combined is limited to 256k.
  // Key can have 2 segments: prefix (optional) and name (required),
  // separated by a slash (/).
  // Prefix must be a DNS subdomain.
  // Name must be 63 characters or less, begin and end with alphanumerics,
  // with dashes (-), underscores (_), dots (.), and alphanumerics between.
  map<string, string> annotations = 22 [(google.api.field_behavior) = OPTIONAL];

  // Required. The constraint on the maximum number of pods that can be run
  // simultaneously on a node in the node pool.
  MaxPodsConstraint max_pods_constraint = 27
      [(google.api.field_behavior) = REQUIRED];

  // Output only. A set of errors found in the node pool.
  repeated AwsNodePoolError errors = 29
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Parameters that describe the nodes in a cluster.
message AwsNodeConfig {
  // Optional. The AWS instance type.
  //
  // When unspecified, it uses a default based on the node pool's version.
  string instance_type = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Template for the root volume provisioned for node pool nodes.
  // Volumes will be provisioned in the availability zone assigned
  // to the node pool subnet.
  //
  // When unspecified, it defaults to 32 GiB with the GP2 volume type.
  AwsVolumeTemplate root_volume = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The initial taints assigned to nodes of this node pool.
  repeated NodeTaint taints = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The initial labels assigned to nodes of this node pool. An object
  // containing a list of "key": value pairs. Example: { "name": "wrench",
  // "mass": "1.3kg", "count": "3" }.
  map<string, string> labels = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Key/value metadata to assign to each underlying AWS resource.
  // Specify at most 50 pairs containing alphanumerics, spaces, and symbols
  // (.+-=_:@/). Keys can be up to 127 Unicode characters. Values can be up to
  // 255 Unicode characters.
  map<string, string> tags = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. The name or ARN of the AWS IAM role assigned to nodes in the
  // pool.
  string iam_instance_profile = 6 [(google.api.field_behavior) = REQUIRED];

  // Optional. The OS image type to use on node pool instances.
  // Can have a value of `ubuntu`, or `windows` if the cluster enables
  // the Windows node pool preview feature.
  //
  // When unspecified, it defaults to `ubuntu`.
  string image_type = 11 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The SSH configuration.
  AwsSshConfig ssh_config = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The IDs of additional security groups to add to nodes in this
  // pool. The manager will automatically create security groups with minimum
  // rules needed for a functioning cluster.
  repeated string security_group_ids = 10
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Proxy configuration for outbound HTTP(S) traffic.
  AwsProxyConfig proxy_config = 12 [(google.api.field_behavior) = OPTIONAL];

  // Required. Config encryption for user data.
  AwsConfigEncryption config_encryption = 13
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Placement related info for this node.
  // When unspecified, the VPC's default tenancy will be used.
  AwsInstancePlacement instance_placement = 14
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Configuration related to CloudWatch metrics collection on the
  // Auto Scaling group of the node pool.
  //
  // When unspecified, metrics collection is disabled.
  AwsAutoscalingGroupMetricsCollection autoscaling_metrics_collection = 15
      [(google.api.field_behavior) = OPTIONAL];
}

// AwsNodePoolAutoscaling contains information required by cluster autoscaler
// to adjust the size of the node pool to the current cluster usage.
message AwsNodePoolAutoscaling {
  // Required. Minimum number of nodes in the node pool. Must be greater than or
  // equal to 1 and less than or equal to max_node_count.
  int32 min_node_count = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Maximum number of nodes in the node pool. Must be greater than or
  // equal to min_node_count and less than or equal to 50.
  int32 max_node_count = 2 [(google.api.field_behavior) = REQUIRED];
}

// AwsServerConfig is the configuration of GKE cluster on AWS.
message AwsServerConfig {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AwsServerConfig"
    pattern: "projects/{project}/locations/{location}/awsServerConfig"
  };

  // The resource name of the config.
  string name = 1;

  // List of valid Kubernetes versions.
  repeated AwsK8sVersionInfo valid_versions = 2;

  // The list of supported AWS regions.
  repeated string supported_aws_regions = 3;
}

// Kubernetes version information of GKE cluster on AWS.
message AwsK8sVersionInfo {
  // Kubernetes version name.
  string version = 1;
}

// SSH configuration for AWS resources.
message AwsSshConfig {
  // Required. The name of the EC2 key pair used to login into cluster machines.
  string ec2_key_pair = 1 [(google.api.field_behavior) = REQUIRED];
}

// Details of a proxy config stored in AWS Secret Manager.
message AwsProxyConfig {
  // The ARN of the AWS Secret Manager secret that contains the HTTP(S) proxy
  // configuration.
  //
  // The secret must be a JSON encoded proxy configuration
  // as described in
  // https://cloud.google.com/anthos/clusters/docs/multi-cloud/aws/how-to/use-a-proxy#create_a_proxy_configuration_file
  string secret_arn = 1;

  // The version string of the AWS Secret Manager secret that contains the
  // HTTP(S) proxy configuration.
  string secret_version = 2;
}

// Config encryption for user data.
message AwsConfigEncryption {
  // Required. The ARN of the AWS KMS key used to encrypt user data.
  string kms_key_arn = 1 [(google.api.field_behavior) = REQUIRED];
}

// Details of placement information for an instance.
// Limitations for using the `host` tenancy:
//
//  * T3 instances that use the unlimited CPU credit option don't support host
//  tenancy.
message AwsInstancePlacement {
  // Tenancy defines how EC2 instances are distributed across physical hardware.
  enum Tenancy {
    // Not set.
    TENANCY_UNSPECIFIED = 0;

    // Use default VPC tenancy.
    DEFAULT = 1;

    // Run a dedicated instance.
    DEDICATED = 2;

    // Launch this instance to a dedicated host.
    HOST = 3;
  }

  // Required. The tenancy for instance.
  Tenancy tenancy = 1 [(google.api.field_behavior) = REQUIRED];
}

// Configuration related to CloudWatch metrics collection in an AWS
// Auto Scaling group.
message AwsAutoscalingGroupMetricsCollection {
  // Required. The frequency at which EC2 Auto Scaling sends aggregated data to
  // AWS CloudWatch. The only valid value is "1Minute".
  string granularity = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The metrics to enable. For a list of valid metrics, see
  // https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_EnableMetricsCollection.html.
  // If you specify Granularity and don't specify any metrics, all metrics are
  // enabled.
  repeated string metrics = 2 [(google.api.field_behavior) = OPTIONAL];
}

// AwsClusterError describes errors found on AWS clusters.
message AwsClusterError {
  // Human-friendly description of the error.
  string message = 1;
}

// AwsNodePoolError describes errors found on AWS node pools.
message AwsNodePoolError {
  // Human-friendly description of the error.
  string message = 1;
}
