// Copyright 2025 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";
import "google/type/date.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 = "AttachedResourcesProto";
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 customer own infrastructure.
message AttachedCluster {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AttachedCluster"
    pattern: "projects/{project}/locations/{location}/attachedClusters/{attached_cluster}"
  };

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

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

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

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

    // The STOPPING state indicates the cluster is being de-registered.
    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>/attachedClusters/<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. OpenID Connect (OIDC) configuration for the cluster.
  AttachedOidcConfig oidc_config = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The platform version for the cluster (e.g. `1.19.0-gke.1000`).
  //
  // You can list all supported versions on a given Google Cloud region by
  // calling
  // [GetAttachedServerConfig][google.cloud.gkemulticloud.v1.AttachedClusters.GetAttachedServerConfig].
  string platform_version = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The Kubernetes distribution of the underlying attached cluster.
  //
  // Supported values: ["eks", "aks", "generic"].
  string distribution = 16 [(google.api.field_behavior) = REQUIRED];

  // Output only. The region where this cluster runs.
  //
  // For EKS clusters, this is a AWS region. For AKS clusters,
  // this is an Azure region.
  string cluster_region = 22 [(google.api.field_behavior) = OUTPUT_ONLY];

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

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

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

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

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

  // Output only. The time at which this cluster was last updated.
  google.protobuf.Timestamp update_time = 10
      [(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 = 11;

  // Output only. The Kubernetes version of the cluster.
  string kubernetes_version = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // 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 = 13 [(google.api.field_behavior) = OPTIONAL];

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

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

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

  // Optional. Configuration related to the cluster RBAC settings.
  AttachedClustersAuthorization authorization = 21
      [(google.api.field_behavior) = OPTIONAL];

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

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

  // Optional. Binary Authorization configuration for this cluster.
  BinaryAuthorization binary_authorization = 25
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Security Posture configuration for this cluster.
  SecurityPostureConfig security_posture_config = 26
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Input only. Tag keys and values directly bound to this resource.
  //
  // The tag key must be specified in the format
  // `<tag namespace>/<tag key name>,`
  // where the tag namespace is the ID of the organization or name of the
  // project that the tag key is defined in. The short name of a tag key or
  // value can have a maximum length of 256 characters. The permitted character
  // set for the short name includes UTF-8 encoded Unicode characters except
  // single quotation marks (`'`), double quotation marks (`"`), backslashes
  // (`\`), and forward slashes (`/`).
  //
  // See
  // [Tags](https://cloud.google.com/resource-manager/docs/tags/tags-overview)
  // for more details on Google Cloud Platform tags.
  map<string, string> tags = 27 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = INPUT_ONLY
  ];

  // Optional. Kubernetes configurations for auto-installed components on the
  // cluster.
  SystemComponentsConfig system_components_config = 28
      [(google.api.field_behavior) = OPTIONAL];
}

// Configuration related to the cluster RBAC settings.
message AttachedClustersAuthorization {
  // Optional. 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 AttachedClusterUser admin_users = 1
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Groups of users that can perform operations as a cluster admin. A
  // managed ClusterRoleBinding will be created to grant the `cluster-admin`
  // ClusterRole to the groups. Up to ten admin groups can be provided.
  //
  // For more info on RBAC, see
  // https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
  repeated AttachedClusterGroup admin_groups = 2
      [(google.api.field_behavior) = OPTIONAL];
}

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

// Identities of a group-type subject for Attached clusters.
message AttachedClusterGroup {
  // Required. The name of the group, e.g. `my-group@domain.com`.
  string group = 1 [(google.api.field_behavior) = REQUIRED];
}

// OIDC discovery information of the target cluster.
//
// Kubernetes Service Account (KSA) tokens are JWT tokens signed by the cluster
// API server. This fields indicates how Google Cloud Platform services
// validate KSA tokens in order to allow system workloads (such as GKE Connect
// and telemetry agents) to authenticate back to Google Cloud Platform.
//
// Both clusters with public and private issuer URLs are supported.
// Clusters with public issuers only need to specify the `issuer_url` field
// while clusters with private issuers need to provide both
// `issuer_url` and `oidc_jwks`.
message AttachedOidcConfig {
  // A JSON Web Token (JWT) issuer URI. `issuer` must start with `https://`.
  string issuer_url = 1;

  // Optional. OIDC verification keys in JWKS format (RFC 7517).
  // It contains a list of OIDC verification keys that can be used to verify
  // OIDC JWTs.
  //
  // This field is required for cluster that doesn't have a publicly available
  // discovery endpoint. When provided, it will be directly used
  // to verify the OIDC JWT asserted by the IDP.
  bytes jwks = 2 [(google.api.field_behavior) = OPTIONAL];
}

// AttachedServerConfig provides information about supported
// Kubernetes versions
message AttachedServerConfig {
  option (google.api.resource) = {
    type: "gkemulticloud.googleapis.com/AttachedServerConfig"
    pattern: "projects/{project}/locations/{location}/attachedServerConfig"
  };

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

  // List of valid platform versions.
  repeated AttachedPlatformVersionInfo valid_versions = 2;
}

// Information about a supported Attached Clusters platform version.
message AttachedPlatformVersionInfo {
  // Platform version name.
  string version = 1;

  // Optional. True if the version is available for attachedcluster creation. If
  // a version is enabled, it can be used to attach new clusters.
  bool enabled = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. True if this cluster version belongs to a minor version that has
  // reached its end of life and is no longer in scope to receive security and
  // bug fixes.
  bool end_of_life = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The estimated date (in Pacific Time) when this cluster version
  // will reach its end of life. Or if this version is no longer supported (the
  // `end_of_life` field is true), this is the actual date (in Pacific time)
  // when the version reached its end of life.
  google.type.Date end_of_life_date = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The date (in Pacific Time) when the cluster version was released.
  google.type.Date release_date = 6 [(google.api.field_behavior) = OPTIONAL];
}

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

// Details of a proxy config.
message AttachedProxyConfig {
  // The Kubernetes Secret resource that contains the HTTP(S) proxy
  // configuration. The secret must be a JSON encoded proxy configuration
  // as described in
  // https://cloud.google.com/kubernetes-engine/multi-cloud/docs/attached/eks/how-to/use-a-proxy#configure-proxy-support
  // for EKS clusters and
  // https://cloud.google.com/kubernetes-engine/multi-cloud/docs/attached/aks/how-to/use-a-proxy#configure-proxy-support
  // for AKS clusters.
  KubernetesSecret kubernetes_secret = 1;
}

// Information about a Kubernetes Secret
message KubernetesSecret {
  // Name of the kubernetes secret.
  string name = 1;

  // Namespace in which the kubernetes secret is stored.
  string namespace = 2;
}

// SystemComponentsConfig defines the fields for customizing configurations for
// auto-installed components.
message SystemComponentsConfig {
  // Sets custom tolerations for pods created by auto-installed components.
  repeated Toleration tolerations = 1;

  // Sets custom labels for pods created by auto-installed components.
  repeated Label labels = 2;
}

// Toleration defines the fields for tolerations for pods created by
// auto-installed components.
message Toleration {
  // KeyOperator represents a key's relationship to the value e.g. 'Equal'.
  enum KeyOperator {
    // Operator is not specified.
    KEY_OPERATOR_UNSPECIFIED = 0;

    // Operator maps to 'Equal'.
    KEY_OPERATOR_EQUAL = 1;

    // Operator maps to 'Exists'.
    KEY_OPERATOR_EXISTS = 2;
  }

  // Effect indicates the taint effect to match e.g. 'NoSchedule'.
  enum Effect {
    // Effect is not specified.
    EFFECT_UNSPECIFIED = 0;

    // Effect maps to 'NoSchedule'.
    EFFECT_NO_SCHEDULE = 1;

    // Effect maps to 'PreferNoSchedule'.
    EFFECT_PREFER_NO_SCHEDULE = 2;

    // Effect maps to 'NoExecute'.
    EFFECT_NO_EXECUTE = 3;
  }

  // Key is the taint key that the toleration applies to.
  string key = 1;

  // Value is the taint value that the toleration applies to.
  string value = 2;

  // KeyOperator represents a key's relationship to the value e.g. 'Exist'.
  KeyOperator key_operator = 3;

  // Effect indicates the taint effect to match e.g. 'NoSchedule'
  Effect effect = 4;
}

// Label defines the additional fields for labels for pods created by
// auto-installed components.
message Label {
  // This is the key of the label.
  string key = 1;

  // This is the value of the label.
  string value = 2;
}
